一图书信息管理系统
题目要求
图书信息包括:登录号、书名、作者名、分类号、出版单位、出版时间、价格等。
试设计一图书信息管理系统,使之能提供以下功能:
系统以菜单方式工作
图书信息录入功能(图书信息用文件保存)--输入
图书信息浏览功能--输出
查询和排序功能:(至少一种查询方式)--算法
(1) 按书名查询
(2) 按作者名查询
图书信息的删除与修改(可选项)v
[提示]建立职工信息结构体,结构体成员包括职工号、姓名、性别、年龄、学历、工资、住址、电话。
需求分析
根据题目要求,要求对图书信息进行输入、输出等操作;在程序中需要浏览图书的信息,应提供显示、查找、浏览、插入、修改等操作;另外还应提供键盘式选择菜单实现功能选择。
总体设计
根据需求分析,可以对这个系统的设计分为以下几个模块:
图 系统功能模块图
详细设计
主函数
主函数一般设计得比较简洁,只提供输入,处理和输出部分的函数调用。其中各功能模块用菜单方式选择。
[流程图]:
SHAPE \* MERGEFORMAT
图 主函数流程图
[程序]:
/*****************主函数**********************/
main ()
{menu();
}
/*****************menu函数********************/
void menu()
{ int n,w1;/*变量n保存选择菜单数字,w1判断输入的数字是否在功能菜单对应数字范围*/
do
{
puts("\t\t*****************menu****************\n\n");
puts("\t\t\t\ new data");
puts("\t\t\t\ all");
puts("\t\t\t\ ");
puts("\t\t\t\");
puts("\t\t\t\");
puts("\n\n\t\t***********************************\n");
printf("Choice your number(1-5):[ ]\b\b");
scanf("%d",&n);
if(n<1||n>5) /*对选择的数字作出判断,是否在菜单功能数字范围内*/
{w1=1;getchar();}
else w1=0;
} while(w1==1);
switch(n)/*根据输入的数字,进入到相应的操作模块中*/
{case 1:enter();break;/*输入模块*/
case 2:browse();break; /*浏览模块*/
case 3:search();break; /*查找模块,其中包括按不同类别进行查找的多个子模块*/
case 4:add();break;/*插入模块*/
case 5:exit(0); /*退出*/
}
}
注:menu函数能提供菜单方式选择功能,可以根据用户需要进入到所想要的操作模块中,此外把menu函数独立出来,可以方便随时对它进行调用,容易返回到系统界面。
用结构体来存放职工信息:
/********************结构体*******************/
struct worker
{
char number[11];
char name[20];
char sex[20];
char adress[20];
char xueli[20];
char telephone[20];
char age[20];
char salary[20];
}wor[N];
/* wor[N]中每个数组元素对应一个职工*/
其中可以根据宏定义# define N随时对N的值进行调整,扩大信息的储存量。
各功能模块设计
(1)输入模块
[需求分析] 对信息进行输入。
[流程图]:
SHAPE \* MERGEFORMAT
图1 输入模块流程图
[程序]:
/********************输入模块*******************/
void enter()/*输入函数*/
{
int i,n;
printf("How many workers(0-%d):",N-1);
scanf("%d",&n);/*输入记录的个数,赋值给n*/
printf("\n Enter data now\n\n");
for(i=0;i<n;i++)/*通过for循环语句依次输入N个职工信息数据*/
{ printf("\n Input %dth worker record.\n",i+1);
input(i);/*调用单个输入函数*/
}
if(i!=0)save(n);/*调用保存函数*/
printf_back(); /*一个任务结束时让用户选择是浏览还是返回*/
}
(2)浏览模块
[需求分析] 该模块的功能是显示所有职工记录信息。
[流程图]
:
图2 浏览模块流程图
[程序]:
/****************浏览(全部)模块***************/
browse() /*浏览(全部模块)*/
{
int i,j,n;
n=load(); /*调用加载函数,并计算可以记录的个数*/
printf_face(); /*调出显示数据结构项目函数*/
for(i=0;i<n;i++) /* for循环语句用以分屏显示*/
{
if((i!=0)&&(i%10==0))/*判断i值能否整除10,每10行一屏显示*/
{
printf("\n\nPass any key to continue...");
getchar();
puts("\n\n");
}
printf_one(i);/*调用显示一个记录的函数*/
}
printf("\tThere are %d record.\n",n);/*提示用户储存信息数量*/
printf("\nPass any key to back...");
getch();/*按任意键*/
menu();/*返回主菜单*/
}
(3)查找模块
图3 查找模块流程图
[程序]:
/***************查找模块***************/
search() /*查找模块*/
{
int c,w1;
do /* do- while循环语句用来判断用户的选择是否在程序规定之内*/
{
puts("\nsearch by=>\n\n1).number2).xueli3).cancel and back");
printf("Which you needed?:[ ]\b\b");
scanf("%d",&c);
if(c>3||c<1) /*对选择的数字作出判断*/
{
puts("\nchoice error!please again!");
getchar();}
}
while(c>3||c<1);
{
switch(c) /* switch语句提供按不同类别进行查找功能*/
{
case 1:search1();break; /*按职工号进行查找*/
case 2:search2();break; /*按姓名进行查找*/
case 3:menu();break; /*返回主菜单*/
}
}
}
①/***************按职工号查找模块***************/
[流程图]:
图4 按职工号查找模块流程图
[程序]:
search1()
{
int i,n,k,w1=1,w2,w3,w4;
struct worker s; /*定义结构体变量s,用以储存输入的number的值,便于进行比较*/
n=load(); /*加载将要记录的个数*/
do /*该do- while循环语句判断是否继续执行该函数*/
{
do /*该do- while循环语句判断是否找到要查找的对象*/
{
k=-1;
printf("\n\nEnter number that you want to search! number:");
scanf("%s",);
printf_face();/*调出显示数据结构项目函数*/
for(i=0;i<n;i++) /* for循环语句用来判断原数据信息中是否有与输入职工号相
同的职工号*/
if(strcmp(,wor[i].number)==0) /*原数据信息中找到与输入职工号相
同的职工号*/
{ k=i;
printf_one(k);break;
}
if(k==-1) / *原数据信息中没有找到与输入职工号相同的职工号*/
{
printf("\n\nNo exit!please");
printf("\n\nAre you again?\n\t1).again 2).No and back [ ]\b\b");
scanf("%d",&w1);
if(w1==2) menu();/*返回主菜单*/
}
}while(k==-1&&w1==1);/*在没有找到且想再次查找的情况下继续进行循环*/
w4=0;w3=0;
if(k!=-1) /*在查找到的情况下*/
{
printf("\n\nWhat do you want to do?\n\t1).Search another 2).Modify 3).Back menu [ ]\b\b");
scanf("%d",&w2);
switch(w2)
{case 1:search1();break;/*继续按照职工号查找其他对象*/
case 2:w3=modify_data(k,n);break;/*对查找到的对象进行修改*/
case 3:menu();break;/*返回主菜单*/
}
}
}while(w2==1);
menu();/*返回主菜单*/
}
②/***************按学历查找模块***************/
[流程图]
图5按职工学历查找模块流程图
[程序]:
search2()
{int i,n,k,w1=1,w2,w3,w4;
struct worker s; /*定义结构体变量s,用以储存输入的xueli的值,便于进行比较*/
n=load(); /*加载将要记录的个数*/
do /*该do- while循环语句判断是否继续执行该函数*/
{
do /*该do- while循环语句判断是否找到要查找的对象*/
{k=-1;
printf("\n\nEnter xueli that you want to search! xueli:");
scanf("%s", );
printf_face();/*调出显示数据结构项目函数*/
for(i=0;i<n;i++) /* for循环语句用来判断原数据信息中是否有与输入职工学历相同的
职工*/
if(strcmp(s. xueli,wor[i]. xueli)==0) /*原数据信息中找到与输入职工学历相同的职工*/
{k=i;
printf_one(k);break;
}
if(k==-1) / *原数据信息中没有找到与输入职工学历相同的职工*/
{printf("\n\nNo exit!please");
printf("\n\nAre you again?\n\t1).again 2).No and back [ ]\b\b");
scanf("%d",&w1);
if(w1==2) menu();/*返回主菜单*/
}
}
while(k==-1&&w1==1);/*在没有找到且想再次查找的情况下继续进行循环*/
w4=0;w3=0;
if(k!=-1) /*在查找到的情况下*/
{printf("\n\nWhat do you want to do?\n\t1).Search another 2).Modify 3).Back menu [ ]\b\b");
scanf("%d",&w2);
switch(w2)
{case 1:search1();break;/*继续按照职工学历查找其他对象*/
case 2:w3=modify_data(k,n);break;/*对查找到的对象进行修改*/
case 3:menu();break;/*返回主菜单*/
}
}
}
while(w2==1);
menu();/*返回主菜单*/
}
(4)插入模块
[需求分析] 该模块的功能是插入职工记录信息并且不能覆盖原有职工信息。
[流程图]
图6插入模块流程图
【程序】
/*************************插入模块*********************/
add() /*插入模块*/
{
int i,n,m,k;
FILE*fp;
n=load(); /*加载将要记录的个数*/
printf("How many worker are you want to add(0-%d)?:",N-1-n);
scanf("%d",&m); /*输入要查如职工信息的个数*/
k=m+n;
for(i=n;i<k;i++) /*用for循环实现m个信息的录入*/
{
printf("\nInput %dth workers record.\n",i-n+1 );
input(i); /*调用整条职工信息输入函数*/
}
if((fp=fopen("","ab"))==NULL)
{
printf("cannot open file\n");
}
for(i=n;i<k;i++) /*用for循环实现对m个信息录入到文件 */
if(fwrite(&wor[i],sizeof(struct worker),1,fp)!=1)
printf("file write error\n");
fclose(fp);
printf_back(); /*一个任务结束时的选择浏览还是返回的函数*/
}
公共函数
(1)保存函数 save(int n)
[说明]:形参n控制保存的个数。
[程序]:
void save(int n)
{FILE *fp; /*定义文件指针*/
int i;
if((fp=fopen("","wb"))==NULL)/*以只写方式打开二进制文件,若打不开返回NULL值*/
{printf("\nCannot open file\n");
}
for(i=0;i<n;i++) /* for循环语句作用为读写n个数据块*/
if(fwrite(&wor[i],sizeof(struct worker),1,fp)!=1)/*若读写成功,则返回值1*/
printf("file write error\n");
fclose(fp); /*关闭文件*/
}
(2)加载函数 load()
[说明]:该函数可以用来加载所有记录,并且可以返回所有记录的个数。
[程序]:
int load()
{FILE *fp;
int i;
if((fp=fopen("","rb"))==NULL) /*以只读方式打开二进制文件,若打不开返回NULL值*/
{printf("\nCannot open file\n");
return NULL;}
for(i=0;!feof(fp);i++)/*在文件关闭之前,向磁盘文件中读入数据块*/
fread(&wor[i],sizeof(struct worker),1,fp);
fclose(fp);
return(i-1); /*返回数据块数值*/
}
(3)职工号输入函数no_input(int i,int n)
[说明]:该函数对输入职工号进行判断,确保输入的职工号唯一。形参i表示第i个职工记录,形参n表示总共有n个职工记录。
[程序]:
void no_input(int i,int n)
{int j,k,w1;
do /*该do- while循环语句用来输入职工号信息并判断号码是否重复*/
{w1=0;
printf("number:");
scanf("%s",wor[i].number);
for(j=0;wor[i].number[j]!='\0';j++) /*判断输入的号码是否由0-9间的数字组成*/
if(wor[i].number[j]<'0'||wor[i].number[j]>'9')/*输入数字不是有0-9之间的数字组成*/
{puts("Input error!Only be made up of (0-9).Please reinput!\n");
w1=1;break;}
if(w1!=1) /* w1!=1表示输入数字正确*/
for(k=0;k<n;k++)
if(k!=i&&strcmp(wor[k].number,wor[i].number)==0) /*判断输入的职工号是否已经重复*/
{puts("This record is reinput!\n");
w1=1;break;}
}
while(w1==1); /* w1==1表示输入数字有误或者输入的职工号重复*/
}
(4)输入整一个记录函数input(int i)
[说明]:形参i表示第i个职工记录。
[程序]:
void input(int i)
{no_input(i,i); /*调用职工号输入函数*/
printf("name:");scanf("%s",wor[i].name);
printf("age:");scanf("%s",wor[i].age);
printf("sex:");scanf("%s",wor[i].sex);
printf("adress:");scanf("%s",wor[i].adress);
printf("telephone:");scanf("%s",wor[i].telephone);
printf("salary:");scanf("%s",wor[i].salary);
printf("xueli:");scanf("%s",wor[i].xueli);
}
(5)显示一个记录的函数 printf_one(int i)
[说明]:形参i表示第i个职工记录。
[程序]:
void printf_one(int i)
{
printf("%11s %6s %9s %3s %8s %11s %7s %6s\n",
wor[i].number,wor[i].name,wor[i].age,wor[i].sex,wor[i].adress,
wor[i].telephone,wor[i].salary,wor[i].xueli);
}
(6)一个任务结束时的选择浏览还是返回的函数printf_back()
void printf_back()
{int k,w;
printf("\n\n\tSuccessful^-^.\n\n");
printf("What do you want to do?\n\n\t1).Browse all now\t2).Back: [ ]\b\b");
scanf("%d",&w);
if(w==1)browse(); /*输入1再次浏览*/
else menu();}/*返回主菜单*/
(7)修改整条数据记录函数modify_data(int i,int n)
[说明]:形参i表示第i个职工记录,形参n 表示有n个记录,此函数带回保存控制值w1,当w1=1时表示确认保存。
[程序]:
modify_data(int i,int n)
{int c,w1;
do /*判断输入数字是否在选择范围之内*/
{puts("\nmodify by=>\n\n 1).number 2).name 3).cancel and back");
printf("Which you needed?:[ ]\b\b");
scanf("%d",&c);
if(c>3||c<1) /*输入数字不在选择范围之内*/
{puts("\nChoice error!please again!");getchar();}
}
while(c>3||c<1);
do /*按照选择输出对应数据块*/
{switch(c)
{case 1:no_input(i,n);break;
case 2:printf("name:");scanf("%s",wor[i].name);break;
case 3:menu();break;}
puts("\nNow:\n");
printf_face();
printf_one(i); /*显示一个记录的函数 */
printf("\nAre you sure?\n\n\t1).sure 2).no and remodify 3).back without save in this time [ ]\b\b");
scanf("%d",&w1);
if(w1==1)save(n); /*对所输入或修改数据进行保存*/
}
while(w1==2);
return(w1);/*返回保存控制值*/
}
上机操作
数据源;
编译、连接和运行;
结果;
下面是各个模块的截面图:
主菜单函数
图7主菜单截图
输入模块:主界面出现后输入1回车显示下图:
图8输入模块截图
输入要输入的记录然后逐条增加,并进行职工号是否重复的检查,如重复则显示输入重复请重新输入:
如下图:
图9 截图
浏览模块
图10浏览模块截图
查找模块
图11 截图
①按职工号查找
图12 按职工号查询截图
②按学历查找
图13 按学历查询截图
③查找到后进行修改
图14 查询后修改
插入职工记录
插入一名职工信息后按1浏览全部职工信息。
如下图:
图15 插入模块截图
附:源程序代码
#include<>
#define N 50
struct worker
{char number[11];
char name[20];
char sex[20];
char adress[20];
char xueli[20];
char telephone[20];
char age[20];
char salary[20];
}wor[N];
void save(int n)
{FILE *fp;
int i;
if((fp=fopen("","wb"))==NULL)
{printf("\nCannot open file\n");
}
for(i=0;i<n;i++)
if(fwrite(&wor[i],sizeof(struct worker),1,fp)!=1)
printf("file write error\n");
fclose(fp);
}
int load()
{FILE *fp;
int i;
if((fp=fopen("","rb"))==NULL)
{printf("\nCannot open file\n");
return NULL;}
for(i=0;!feof(fp);i++)
fread(&wor[i],sizeof(struct worker),1,fp);
fclose(fp);
return(i-1);
}
void no_input(int i,int n)
{int j,k,w1;
do
{w1=0;
printf("number:");
scanf("%s",wor[i].number);
for(j=0;wor[i].number[j]!='\0';j++)
if(wor[i].number[j]<'0'||wor[i].number[j]>'9')
{puts("Input error!Only be made up of (0-9).Please reinput!\n");
w1=1;break;}
if(w1!=1)
for(k=0;k<n;k++)
if(k!=i&&strcmp(wor[k].number,wor[i].number)==0)
{puts("This record is reinput!\n");
w1=1;break;}
}
while(w1==1);
}
void input(int i)
{no_input(i,i);
printf("name:");scanf("%s",wor[i].name);
printf("age:");scanf("%s",wor[i].age);
printf("sex:");scanf("%s",wor[i].sex);
printf("adress:");scanf("%s",wor[i].adress);
printf("telephone:");scanf("%s",wor[i].telephone);
printf("salary:");scanf("%s",wor[i].salary);
printf("xueli:");scanf("%s",wor[i].xueli);
}
void printf_one(int i)
{
printf("%11s %6s %9s %3s %8s %11s %7s %6s\n",
wor[i].number,wor[i].name,wor[i].age,wor[i].sex,wor[i].adress,
wor[i].telephone,wor[i].salary,wor[i].xueli);
}
void printf_back()
{int k,w;
printf("\n\n\tSuccessful^-^.\n\n");
printf("What do you want to do?\n\n\t1).Browse all now\t2).Back: [ ]\b\b");
scanf("%d",&w);
if(w==1)browse();
else menu();}
modify_data(int i,int n)
{int c,w1;
do
{puts("\nmodify by=>\n\n 1).number 2).name 3).cancel and back");
printf("Which you needed?:[ ]\b\b");
scanf("%d",&c);
if(c>3||c<1)
{puts("\nChoice error!please again!");getchar();}
}
while(c>3||c<1);
do
{switch(c)
{case 1:no_input(i,n);break;
case 2:printf("name:");scanf("%s",wor[i].name);break;
case 3:menu();break;}
puts("\nNow:\n");
printf_face();
printf_one(i);
printf("\nAre you sure?\n\n\t1).sure 2).no and remodify 3).back without save in this time [ ]\b\b");
scanf("%d",&w1);
if(w1==1)save(n);
}
while(w1==2);
return(w1);
}
printf_face()
{printf("\n\tnumber name age sex adress telephone salary xueli \n");
}
void enter()
{int i,n;
printf("How many workers(0-%d):",N-1);
scanf("%d",&n);
printf("\n Enter data now\n\n");
for(i=0;i<n;i++)
{printf("\n Input %dth worker record.\n",i+1);
input(i);
}
if(i!=0)save(n);
printf_back();
}
browse()
{int i,j,n;
n=load();
printf_face();
for(i=0;i<n;i++)
{if((i!=0)&&(i%10==0))
{printf("\n\nPass any key to continue...");
getchar();
puts("\n\n");
}
printf_one(i);
}
printf("\tThere are %d record.\n",n);
printf("\nPass any key to back...");
getch();
menu();
}
search()
{int c,w1;
do
{puts("\nsearch by=>\n\n1).number2}.xueli3).cancel and back");
printf("Which you needed?:[ ]\b\b");
scanf("%d",&c);
if(c>3||c<1)
{puts("\nchoice error!please again!");
getchar();}
}
while(c>3||c<1);
{switch(c)
{case 1:search1();break;
case 2:search2();break;
case 3:menu();break;}
}
}
search1()
{int i,n,k,w1=1,w2,w3,w4;
struct worker s;
n=load();
do
{
do
{k=-1;
printf("\n\nEnter number that you want to search! number:");
scanf("%s",);
printf_face();
for(i=0;i<n;i++)
if(strcmp(,wor[i].number)==0)
{k=i;
printf_one(k);break;
}
if(k==-1)
{printf("\n\nNo exit!please");
printf("\n\nAre you again?\n\t1).again 2).No and back [ ]\b\b");
scanf("%d",&w1);
if(w1==2) menu();
}
}
while(k==-1&&w1==1);
w4=0;w3=0;
if(k!=-1)
{printf("\n\nWhat do you want to do?\n\t1).Search another 2).Modify 3).Back menu [ ]\b\b");
scanf("%d",&w2);
switch(w2)
{case 1:search1();break;
case 2:w3=modify_data(k,n);break;
case 3:{menu();
break;
}
}
}
}
while(w2==1);
menu();
}
search2()
{int i,n,k,w1=1,w2,w3,w4;
struct worker s;
n=load();
do
{
do
{k=-1;
printf("\n\nEnter xueli that you want to search! xueli:");
scanf("%s",);
printf_face();
for(i=0;i<n;i++)
if(strcmp(,wor[i].xueli)==0)
{k=i;
printf_one(k);
}
if(k==-1)
{printf("\n\nNo exit!please");
printf("\n\nAre you again?\n\t1).again 2).No and back [ ]\b\b");
scanf("%d",&w1);
if(w1==2) menu();
}
}
while(k==-1&&w1==1);
w4=0;w3=0;
if(k!=-1)
{printf("\n\nWhat do you want to do?\n\t1).Search another 2).Modify 3).Back menu [ ]\b\b");
scanf("%d",&w2);
switch(w2)
{case 1:search2();break;
case 2:w3=modify_data(k,n);break;
case 3:{menu();
break;
}
}
}
}
while(w2==1);
menu();
}
add()
{
int i,n,m,k;
FILE*fp;
n=load();
printf("How many workers are you want to add(0-%d)?:",N-1-n);
scanf("%d",&m);
k=m+n;
for(i=n;i<k;i++)
{
printf("\nInput %dth workers record.\n",i-n+1 );
input(i);
}
if((fp=fopen("","ab"))==NULL)
{
printf("cannot open file\n");
}
for(i=n;i<k;i++)
if(fwrite(&wor[i],sizeof(struct worker),1,fp)!=1)
printf("file write error\n");
fclose(fp);
printf_back();
}
menu()
{int n,w1;
do
{
puts("\t\t*****************menu****************\n\n");
puts("\t\t\t\ new data");
puts("\t\t\t\ all");
puts("\t\t\t\ ");
puts("\t\t\t\");
puts("\t\t\t\");
puts("\n\n\t\t***********************************\n");
printf("Choice your number(1-5):[ ]\b\b");
scanf("%d",&n);
if(n<1||n>5)
{w1=1;getchar();}
else w1=0;
} while(w1==1);
switch(n)
{case 1:enter();break;
case 2:browse();break;
case 3:search();break;
case 4:add();break;
case 5:exit(0);
}
}
main()
{ menu();
}
PAGE