图书管理系统.docx
- 文档编号:8288934
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:19
- 大小:20.14KB
图书管理系统.docx
《图书管理系统.docx》由会员分享,可在线阅读,更多相关《图书管理系统.docx(19页珍藏版)》请在冰豆网上搜索。
图书管理系统
#include"stdio.h"/*标准输入输出函数库*/
#include"stdlib.h"/*标准函数库*/
#include"string.h"/*字符串函数库*/
#defineHEADER1"-----------------------------图书信息--------------------------\n"
#defineHEADER2"|书号|书名|作者|出版社|价格|数量|\n"
#defineHEADER3"|---------------|---------|--------|----------|--------|------|\n"
#defineFORMAT"|%-10s|%-9s|%-8s|%-10s|%6.2f|%4d|\n"
#defineDATAp->data.num,p->data.name,p->data.author,p->data.press,p->data.price,p->data.total
#defineEND"---------------------------------------------------------------\n"
intsaveflag=0;/*是否需要存盘的标志变量*/
/*定义与图书有关的数据结构*/
typedefstructbook/*标记为book*/
{
charnum[10];/*书号*/
charname[15];/*书名*/
charauthor[8];/*作者*/
charpress[30];/*出版社*/
floatprice;/*价格*/
inttotal;/*数量*/
};
/*定义每条记录或结点的数据结构,标记为:
node*/
typedefstructnode
{
structbookdata;/*数据域*/
structnode*next;/*指针域*/
}Node,*Link;/*Node为node类型的结构变量,*Link为node类型的指针变量*/
voidmenu()/*主菜单*/
{
system("cls");/*调用DOS命令,清屏.与clrscr()功能相同*/
printf("\n\n图书管理系统\n\n");
printf("***************************主菜单****************************\n");
printf("*1输入图书信息2删除图书信息*\n");
printf("*3查找图书记录4修改图书记录*\n");
printf("*5插入图书记录6显示图书记录*\n");
printf("*7保存图书记录0退出系统*\n");
printf("*************************************************************\n");
}
voidprintheader()/*格式化输出表头*/
{
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
}
voidprintdata(Node*pp)/*格式化输出表中数据*/
{
Node*p;
p=pp;
printf(FORMAT,DATA);
}
voidWrong()/*输出按键错误信息*/
{
printf("\n\n\n\n\n***********错误:
输入有错!
请按任意键继续**********\n");
getchar();
}
voidNofind()/*输出未查找此图书的信息*/
{
printf("\n=====>没有找到这本图书!
\n");
}
voidDisp(Linkl)/*显示单链表l中存储的图书记录,内容为book结构中定义的内容*/
{
Node*p;
p=l->next;/*l存储的是单链表中头结点的指针,该头结点没有存储图书信息,指针域指向的后继结点才有图书信息*/
if(!
p)/*p==NULL,NUll在stdlib中定义为0*/
{
printf("\n=====>没有图书记录!
\n");
getchar();
return;
}
printf("\n\n");
printheader();/*输出表格头部*/
while(p)/*逐条输出链表中存储的图书信息*/
{
printdata(p);
p=p->next;/*移动直下一个结点*/
printf(HEADER3);
}
getchar();getchar();
}
/*************************************************************
作用:
用于定位链表中符合要求的节点,并返回指向该节点的指针
参数:
findmess[]保存要查找的具体内容;nameornum[]保存按什么查找;
在单链表l中查找;
**************************************************************/
Node*Locate(Linkl,charfindmess[],charnameornum[])
{
Node*r;
if(strcmp(nameornum,"num")==0)/*按书号查询*/
{
r=l->next;
while(r)
{
if(strcmp(r->data.num,findmess)==0)/*若找到findmess值的书号*/
returnr;
r=r->next;
}
}
elseif(strcmp(nameornum,"name")==0)/*按书名查询*/
{
r=l->next;
while(r)
{
if(strcmp(r->data.name,findmess)==0)/*若找到findmess值的图书名*/
returnr;
r=r->next;
}
}
return0;/*若未找到,返回一个空指针*/
}
/*输入字符串,并进行长度验证(长度 voidstringinput(char*t,intlens,char*notice) { charn[255]; do{ printf(notice);/*显示提示信息*/ scanf("%s",n);/*输入字符串*/ if(strlen(n)>lens)printf("\n串长超限了! 请重新输入。 \n");/*进行长度校验,超过lens值重新输入*/ }while(strlen(n)>lens); strcpy(t,n);/*将输入的字符串拷贝到字符串t中*/ } /*输入数量,1<=数量<=1000)*/ intnumberinput(char*notice) { intt=0; do{ printf(notice);/*显示提示信息*/ scanf("%d",&t);/*输入数量*/ if(t>1000||t<1)printf("\n数量必须在[1,1000]之间! \n");/*进行数量校验*/ }while(t>1000||t<1); returnt; } /*增加图书记录*/ voidAdd(Linkl) { Node*p,*r,*s;/*实现添加操作的临时的结构体指针变量*/ charch,flag=0,num[10]; r=l; s=l->next; system("cls"); Disp(l);/*先打印出已有的图书信息*/ while(r->next! =NULL) r=r->next;/*将指针移至于链表最末尾,准备添加记录*/ while (1)/*一次可输入多条记录,直至输入书号为0的记录结束添加操作*/ { while (1)/*输入书号,保证该书号没有被使用,若输入书号为0,则退出添加记录操作*/ { stringinput(num,10,"输入书号(按'0'返回菜单): ");/*格式化输入书号并检验*/ flag=0; if(strcmp(num,"0")==0)/*输入为0,则退出添加操作,返回主界面*/ {return;} s=l->next; while(s)/*查询该书号是否已经存在,若存在则要求重新输入一个未被占用的书号*/ { if(strcmp(s->data.num,num)==0) { flag=1; break; } s=s->next; } if(flag==1)/*提示用户是否重新输入*/ {getchar(); printf("=====>书号%s已存在,是否重新输入? (y/n): ",num); scanf("%c",&ch); if(ch=='y'||ch=='Y') continue; else return; } else {break;} } p=(Node*)malloc(sizeof(Node));/*申请内存空间*/ if(! p) { printf("\n没有申请到内存空间");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } strcpy(p->data.num,num);/*将字符串num拷贝到p->data.num中*/ stringinput(p->data.name,15,"书名: "); stringinput(p->data.author,8,"作者: "); stringinput(p->data.press,30,"出版社: "); printf("请输入图书的价格: "); scanf("%f",&p->data.price); p->data.total=numberinput("图书数量范围是[1-1000]: ");/*输入并检验数量,数量必须在1-1000之间*/ p->next=NULL;/*表明这是链表的尾部结点*/ r->next=p;/*将新建的结点加入链表尾部中*/ r=p; saveflag=1; } return; } voidQur(Linkl)/*按书号或书名,查询图书记录*/ { intselect;/*1: 按书号查,2: 按书名查,其他: 返回主界面(菜单)*/ charsearchinput[20];/*保存用户输入的查询内容*/ Node*p; if(! l->next)/*若链表为空*/ { system("cls"); printf("\n=====>没有图书记录! \n"); getchar(); return; } system("cls"); printf("\n=====>1通过书号查找=====>2通过书名查找\n"); printf("请选择[1,2]: "); scanf("%d",&select); if(select==1)/*按书号查询*/ { stringinput(searchinput,10,"输入存在的图书书号: "); p=Locate(l,searchinput,"num");/*在l中查找书号为searchinput值的节点,并返回节点的指针*/ if(p)/*若p! =NULL*/ { printheader(); printdata(p); printf(END); printf("按任何一个键返回"); getchar(); } else Nofind(); getchar(); } elseif(select==2)/*按书名查询*/ { stringinput(searchinput,15,"输入存在的图书书名: "); p=Locate(l,searchinput,"name"); if(p) { printheader(); printdata(p); printf(END); printf("按任何一个键返回"); getchar(); } else Nofind(); getchar(); } else Wrong(); getchar(); } /*删除图书记录: 先找到保存该图书记录的节点,然后删除该节点*/ voidDel(Linkl) { intsel; Node*p,*r; charfindmess[20]; if(! l->next) {system("cls"); printf("\n=====>没有图书记录! \n"); getchar(); return; } system("cls"); Disp(l); printf("\n=====>1通过书号删除=====>2通过书名删除\n"); printf("请选择[1,2]: "); scanf("%d",&sel); if(sel==1) { stringinput(findmess,10,"输入存在的图书书号: "); p=Locate(l,findmess,"num"); if(p)/*p! =NULL*/ { r=l; while(r->next! =p) r=r->next; r->next=p->next;/*将p所指节点从链表中去除*/ free(p);/*释放内存空间*/ printf("\n=====>删除成功! \n"); getchar(); saveflag=1; } else Nofind(); getchar(); } elseif(sel==2)/*先按书名查询到该记录所在的节点*/ { stringinput(findmess,15,"输入存在的图书书名"); p=Locate(l,findmess,"name"); if(p) { r=l; while(r->next! =p) r=r->next; r->next=p->next; free(p); printf("\n=====>成功删除! \n"); getchar(); saveflag=1; } else Nofind(); getchar(); } else Wrong(); getchar(); } /*修改图书记录。 先按输入的书号查询到该记录,然后提示用户修改书号之外的值,书号不能修改*/ voidModify(Linkl) { Node*p; charfindmess[20]; if(! l->next) {system("cls"); printf("\n=====>没有图书记录! \n"); getchar(); return; } system("cls"); printf("\n修改以下图书记录: "); Disp(l); stringinput(findmess,10,"输入存在的图书书号: ");/*输入并检验该书号*/ p=Locate(l,findmess,"num");/*查询到该节点*/ if(p)/*若p! =NULL,表明已经找到该节点*/ { printf("书号: %s,\n",p->data.num); printf("书名: %s,",p->data.name); stringinput(p->data.name,15,"输入新的书名: "); printf("作者: %s,",p->data.author); stringinput(p->data.author,8,"输入新的作者名: "); printf("出版社: %s,",p->data.press); stringinput(p->data.press,30,"输入新的出版社名: "); printf("图书的价格: %4.2f,",p->data.price); printf("修改后的图书的价格: "); scanf("%f",&p->data.price); printf("图书的数量: %d,",p->data.total); p->data.total=numberinput("修改后的图书的数量: "); printf("\n=====>修改成功! \n"); Disp(l); saveflag=1; } else Nofind(); getchar(); } /*插入记录: 按书号查询到要插入的节点的位置,然后在该书号之后插入一个新节点。 */ voidInsert(Linkl) { Linkp,v,newinfo;/*p指向插入位置,newinfo指新插入记录*/ charch,num[10],s[10];/*s[]保存插入点位置之前的书号,num[]保存输入的新记录的书号*/ intflag=0; v=l->next; system("cls"); Disp(l); while (1) {stringinput(s,10,"请输入一个书号,在该书号之后插入: "); flag=0;v=l->next; while(v)/*查询该书号是否存在,flag=1表示该书号存在*/ { if(strcmp(v->data.num,s)==0){flag=1;break;} v=v->next; } if(flag==1) break;/*若书号存在,则进行插入之前的新记录的输入操作*/ else {getchar(); printf("\n=====>书号%s不存在,请重新输入? (y/n): ",s); scanf("%c",&ch); if(ch=='y'||ch=='Y') {continue;} else {return;} } } /*以下新记录的输入操作与Add()相同*/ stringinput(num,10,"输入新的图书书号: "); v=l->next; while(v) { if(strcmp(v->data.num,num)==0) { printf("=====>抱歉,新书号: '%s'不存在! \n",num); printheader(); printdata(v); printf("\n"); getchar(); return; } v=v->next; } newinfo=(Node*)malloc(sizeof(Node)); if(! newinfo) { printf("\n动态申请内存失败! ");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } strcpy(newinfo->data.num,num); stringinput(newinfo->data.name,15,"书名: "); stringinput(newinfo->data.author,8,"作者: "); stringinput(newinfo->data.press,30,"出版社: "); //newinfo->data.cgrade=numberinput("C语言成绩[0-100]: "); printf("价格: "); scanf("%f",&newinfo->data.price); newinfo->data.total=numberinput("数量范围是[1-1000]: ");/*输入并检验数量,数量必须在1-1000之间*/ newinfo->next=NULL; saveflag=1;/*在main()有对该全局变量的判断,若为1,则进行存盘操作*/ /*将指针赋值给p,因为l中的头节点的下一个节点才实际保存着学生的记录*/ p=l->next; while (1) { if(strcmp(p->data.num,s)==0)/*在链表中插入一个节点*/ { newinfo->next=p->next; p->next=newinfo; break; } p=p->next; } Disp(l); printf("\n\n"); getchar(); } /*数据存盘,若用户没有专门进行此操作且对数据有修改,在退出系统时,会提示用户存盘*/ voidSave(Linkl) { FILE*fp; Node*p; intcount=0; fp=fopen("c: \\book","wb");/*以只写方式打开二进制文件*/ if(fp==NULL)/*打开文件失败*/ { printf("\n=====>打开文件失败! \n"); getchar(); return; } p=l->next; while(p) { if(fwrite(p,sizeof(Node),1,fp)==1)/*每次写一条记录或一个节点信息至文件*/ { p=p->next; count++; } else { break; } } if(count>0) { getchar(); printf("\n\n\n\n\n=====>记录已保存至磁盘文件,记录总数为: %d\n",count); getchar(); saveflag=0; } else {system("cls"); printf("当前链表是个空表,没有图书记录! \n"); getchar(); } fclose(fp);/*关闭此文件*/ } voidmain() { Linkl;/*定义链表*/ FILE*fp;/*文件指针*/ intselect;/*保存选择结果变量*/ charch;/*保存(y,Y,n,N)*/ intcount=0;/*保存文件中的记录条数(或结点个数)*/ Node*p,*r;/*定义记录指针变量*/ l=(Node*)malloc(sizeof(Node)); if(! l) { printf("\n动态申请内存失败");/*如没有申请到,打印提示信息*/ return;/*返回主界面*/ } l->next=NULL; r=l; fp=fopen("C: \\student","ab+");/*以追加方式打开一个二进制文件,可读可写,若此文件不存在,会创建此文件*/ if(fp==NULL) { printf("\n=====>不能打开
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图书 管理 系统