基于C语言的图书管理系统【链表/文件】

时间:2025-03-07 09:11:58
  • #include<>
  • #include<>
  • #include<string.h>
  • struct book1
  • {
  • char isbn[20];//书号
  • char name[20];//书名
  • char author[20];//作者
  • char print[20];//出版社
  • char zone[15];//编号
  • int amount;//库存量
  • float price;//价格
  • };
  • struct book
  • {
  • struct book1 book1;//图书信息结构体
  • struct book *next;
  • };
  • void menu();//主菜单
  • void menu1();//管理者菜单
  • void menu2();//用户菜单
  • void backmenu1();//实现返回管理者功能菜单函数
  • void backmenu2();//用户功能菜单函数
  • void add(); //增加
  • void display();//显示
  • void display1();
  • void change();//修改
  • void enter();//数据录入
  • void find();//查找
  • void delete();//删除
  • void browser();//浏览
  • void insert();//插入
  • void sort();//排序
  • void lendbook();//借阅
  • void returnbook();//还书
  • struct book *read();//文件数据传入链表
  • void write(struct book *head);//链表数据写入文件
  • int main()
  • {
  • char c;
  • menu();
  • printf("管理员请输入m,用户请输入n,退出请按0\n");
  • scanf("%c",&c);
  • while(c!='0')//当输出不是退出键时
  • {
  • if(c=='m')
  • {
  • backmenu1();//进入管理者功能
  • break;
  • }
  • else
  • if(c=='n')
  • {
  • backmenu2();//进入用户功能
  • break;
  • }
  • else
  • {
  • printf("输入错误请重新输入!\n");
  • scanf("%c",&c);
  • }
  • scanf("%c",&c);
  • }
  • if(c=='0')
  • printf("您已成功退出图书管理系统!\n");
  • return 0;
  • }
  • //登录界面
  • void menu()
  • {
  • system("cls");
  • printf("*-----------------------------------图书管理系统------------------------------------*\n");
  • printf("*-----------------------------------------------------------------------------------*\n");
  • printf("* 登录选项 *\n");
  • printf("* 1.管理员 2.用户 *\n");
  • printf("*-----------------------------------------------------------------------------------*\n");
  • printf("\n");
  • }
  • // 管理员界面
  • void menu1()
  • {
  • system("cls");
  • printf("*---------------------------------图书管理系统-------------------------------------*\n");
  • printf("* *\n");
  • printf("*---------------------------------管理员功能列表-----------------------------------*\n");
  • printf("* *\n");
  • printf("*1.录入图书 2.增加图书 3.显示图书 *\n");
  • printf("*4.修改图书信息 5.查找图书 6.删除图书 *\n");
  • printf("*7.浏览图书 8.图书排序 9.插入图书 *\n");
  • printf("*----------------------------------------------------------------------------------*\n");
  • printf("\n");
  • }
  • //用户界面
  • void menu2()
  • {
  • system("cls");
  • printf("***********************************图书管理系统*************************************\n");
  • printf("* *\n");
  • printf("*----------------------------------用户功能列表------------------------------------*\n");
  • printf("* *\n");
  • printf("*1.借阅书籍 2.查询书籍 3.归还书籍 *\n");
  • printf("*4.浏览书籍 *\n");
  • printf("*----------------------------------------------------------------------------------*\n");
  • printf("\n");
  • }
  • //实现返回管理者功能菜单函数
  • void backmenu1()
  • {
  • FILE *fp;
  • int n=1;
  • while(n!=0)
  • {
  • system("cls");
  • menu1();//在这个循环中,每执行一次功能后会继续显示菜单
  • printf("请选择以上功能,退出系统请按0\n");
  • printf("\n");
  • scanf("%d",&n);
  • fp=fopen("","r");
  • if((n>=3&&n<=9)&&(fp==NULL||fgetc(fp)==EOF))//当无文件或者文件内容空白时且选择非(录入添加显示)功能
  • {
  • printf("没有书籍,建议管理员先录入书籍信息\n");
  • system("pause");
  • }
  • else
  • {
  • switch(n)
  • {
  • case 1:enter();break;
  • case 2:add();break;
  • case 3:display1();break;
  • case 4:change();break;
  • case 5:find();break;
  • case 6:delete();break;
  • case 7:browser();break;
  • case 8:sort();break;
  • case 9:insert();break;
  • }
  • }
  • fclose(fp);
  • }
  • printf("\n");
  • if(n==0)
  • printf("您已成功退出图书管理系统!\n");
  • }
  • //用户功能菜单函数
  • void backmenu2()
  • {
  • FILE *fp;
  • int n=1;
  • while(n!=0)
  • {
  • system("cls");
  • menu2();
  • printf("选择功能,退出请按0\n");
  • scanf("%d",&n);
  • fp=fopen("","r");
  • if((fp==NULL||fgetc(fp)==EOF))//当无文件或者文件内容空白时
  • {
  • printf("图书馆内暂无藏书,请耐心等待\n");
  • system("pause");
  • }
  • else
  • {
  • switch(n)
  • {
  • case 1:lendbook();break;
  • case 2:find();break;
  • case 3:returnbook();break;
  • case 4:browser();break;
  • }
  • }
  • fclose(fp);
  • }
  • if(n==0)
  • {
  • printf("您已成功退出图书管理系统\n");
  • system("pause");
  • }
  • }
  • //文件数据传入链表
  • struct book* read()
  • {
  • FILE *fp;
  • struct book1 book1;
  • struct book *p,*tail=NULL,*head=NULL;
  • fp=fopen("","r");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • while(fscanf(fp,"%s%s%s%s%s%d%f",book1.isbn,book1.zone,book1.name,book1.author,book1.print,&book1.amount,&book1.price)!=EOF)//在文件未遇到结束标志时读取数据
  • {
  • p=(struct book*)malloc(sizeof(struct book));
  • p->book1=book1;
  • if(head==NULL)
  • head=p;
  • if(tail!=NULL)
  • tail->next=p;
  • tail=p;
  • tail->next=NULL;
  • }
  • fclose(fp);
  • return head;
  • }
  • //链表写入文件
  • void write(struct book *head)
  • {
  • FILE *fp;
  • struct book *p=NULL;
  • fp=fopen("","w");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • p=head;
  • while(p)
  • {
  • //将数据写入文件
  • fprintf(fp,"%-20s%-15s%-15s%-15s%-19s%-14d%-12.2f ",p->book1.isbn,p->book1.zone,p->book1.name,p->book1.author,p->book1.print,p->book1.amount,p->book1.price);
  • p=p->next;
  • }
  • fclose(fp);
  • }
  • //数据录入
  • void enter()
  • {
  • FILE *fp;
  • int i,n;
  • struct book1 book1;
  • system("cls");
  • printf("输入录入的书籍数量\n");
  • scanf("%d",&n);
  • printf("按以下格式输入\n");
  • printf("ISBN 分区 书名 作者 出版社 数量 单价\n");
  • fp=fopen("","w");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • for(i=0;i<n;i++)
  • {
  • //将数据写入文件
  • scanf("%s%s%s%s%s%d%f",book1.isbn,book1.zone,book1.name,book1.author,book1.print,&book1.amount,&book1.price);
  • fprintf(fp,"%-20s%-15s%-15s%-15s%-19s%-14d%-12.2f\n",book1.isbn,book1.zone,book1.name,book1.author,book1.print,book1.amount,book1.price);
  • }
  • fclose(fp);
  • }
  • //增加图书
  • void add()
  • {
  • struct book *p=NULL,*p1=NULL,*head=NULL,*p2;
  • char n=1;
  • system("cls");
  • printf("按以下格式输入\n");
  • printf("ISBN 分区 书名 作者 出版社 数量 单价\n");
  • p=head=read();//从文件读取数据
  • p2=(struct book*)malloc(sizeof(struct book));
  • scanf("%s%s%s%s%s%d%f",p2->book1.isbn,p2->book1.zone,p2->book1.name,p2->book1.author,p2->book1.print,&p2->book1.amount,&p2->book1.price);
  • while(p)
  • {
  • if(strcmp(p->book1.name,p2->book1.name)==0)//与已有书籍重名
  • {
  • p->book1.amount++;
  • printf("添加成功\n");
  • printf("原书籍数量增加\n");
  • break;
  • }
  • else
  • p=p->next;
  • }
  • if(head==NULL)
  • head=p2;
  • else
  • {
  • p1=head;
  • while(p1->next!=NULL)
  • p1=p1->next;
  • p1->next=p2;
  • p2->next=NULL;
  • }
  • write(head); //将数据写入文件
  • n=getchar();
  • printf("书籍添加成功\n");
  • display();
  • system("pause");
  • }
  • //显示所有图书
  • void display()
  • {
  • struct book1 book1;
  • FILE *fp;
  • printf("图书馆库存\n");
  • printf("\n");
  • fp=fopen("","r");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • else
  • {
  • printf("ISBN 分区 书名 作者 出版社 数量 单价\n");
  • while(fscanf(fp,"%s%s%s%s%s%d%f",book1.isbn,book1.zone,book1.name,book1.author,book1.print,&book1.amount,&book1.price)!=EOF)
  • {
  • printf("%-20s%-15s%-15s%-15s%-19s%-14d%-12.2f\n",book1.isbn,book1.zone,book1.name,book1.author,book1.print,book1.amount,book1.price);
  • }
  • }
  • fclose(fp);
  • printf("\n");
  • }
  • void display1(){
  • system("cls");
  • display();
  • system("pause");
  • }
  • //修改图书信息
  • void change()
  • {
  • struct book *p,*head,*q=NULL;
  • system("cls");
  • int n=1,amount;
  • char isbn[20]={'\0'},name[20]={'\0'},author[20]={'\0'},print[20]={'\0'},name1[20]={'\0'},zone[15]={'\0'};
  • float price;
  • p=head=read();
  • display();
  • printf("输入要修改的图书书名\n");
  • scanf("%s",name);
  • while(p)
  • {
  • if(strcmp(p->book1.name,name)==0)//查找要修改的书籍,找到后跳出循环
  • {
  • q=p;
  • break;
  • }
  • else
  • p=p->next;
  • }
  • while(n!=0)
  • {
  • printf("请选择您要修改的信息,退出修改请按0\n");
  • printf("*------------------------------------------------------*\n");
  • printf("*1.修改ISBN序号 2.修改作者信息 3.修改出版社信息 *\n");
  • printf("*4.修改数量 5.修改单价 6.修改书名 *\n");
  • printf("*7.修改编号 *\n");
  • printf("*------------------------------------------------------*\n");
  • scanf("%d",&n);
  • switch(n)
  • {
  • case 1: printf("输入新ISBN序号:"); scanf("%s",isbn); strcpy(q->book1.isbn,isbn);break;
  • case 2: printf("输入新作者信息:"); scanf("%s",author); strcpy(q->book1.author,author);break;
  • case 3: printf("输入新出版社信息;");scanf("%s",print); strcpy(q->book1.print,print);break;
  • case 4: printf("输入新数量;"); scanf("%d",&amount); q->book1.amount=amount;break;
  • case 5: printf("输入新单价;"); scanf("%f",&price); q->book1.price=price;break;
  • case 6: printf("输入新书名:"); scanf("%s",name1); strcpy(q->book1.name,name1);break;
  • case 7: printf("输入新编号:"); scanf("%s",zone); strcpy(q->book1.zone,zone);break;
  • /*default :printf("输入错误,请重新输入!\n");break;*/
  • }
  • }
  • write(head); //将修改后的信息存入文件
  • printf("修改成功!\n");
  • display();
  • system("pause");
  • }
  • //查找书籍
  • void find()
  • {
  • struct book *head=NULL,*p;
  • char name[20]={'\0'};
  • int flag=0;
  • char n=1;
  • system("cls");
  • head=read();//让head指向传入文件数据的链表
  • p=head;
  • printf("输入查找书籍相关信息(ISBN/书名/作者)(注意不得超过20个字):\n");
  • scanf("%s",name);
  • while(p)
  • {
  • if(strcmp(p->book1.name,name)==0||strcmp(p->book1.author,name)==0||strcmp(p->book1.isbn,name)==0)
  • {
  • printf("ISBN 分区 书名 作者 出版社 数量 单价\n");
  • printf("%-20s%-15s%-15s%-15s%-19s%-14d%-12.2f\n",p->book1.isbn,p->book1.zone,p->book1.name,p->book1.author,p->book1.print,p->book1.amount,p->book1.price);
  • printf("\n");
  • flag=1;
  • break;
  • }
  • else
  • p=p->next;
  • }
  • if(flag==0)
  • printf("没有此书籍,请确认书名是否正确!\n\n");
  • system("pause");
  • }
  • //浏览书籍的数量
  • void browser()
  • {
  • struct book *p=NULL,*head;
  • system("cls");
  • head=read();
  • p=head;
  • if(p==NULL)
  • printf("没有书籍\n");
  • else
  • {
  • printf("已有书籍如下\n");
  • printf("书名 数量\n");
  • while(p)
  • {
  • printf("%-15s%14d\n",p->book1.name,p->book1.amount);
  • p=p->next;
  • }
  • }
  • system("pause");
  • }
  • //删除书籍
  • void delete()
  • {
  • struct book *p1=NULL,*p2=NULL,*head=NULL;
  • char name[20]={'\0'};
  • char ch;
  • p1=p2=head=read();
  • system("cls");
  • display();
  • printf("\n");
  • printf("输入要删除的书籍名称:\n");
  • scanf("%s",name);
  • while(strcmp(p1->book1.name,name)!=0&&p1!=NULL)//第一本书和要删除的书名不同则一直寻找
  • p1=p1->next;
  • if(head==p1)//如果第一本书名和要删书名相同则换头结点
  • head=head->next;
  • else
  • {
  • while(p2)
  • {
  • if(p2->next==p1)//p2指向p1的所指向结点的前一个
  • {
  • p2->next=p1->next;
  • free(p1);
  • break;
  • }
  • p2=p2->next;
  • }
  • }
  • printf("删除成功!\n");
  • write(head);
  • display();
  • printf("\n");
  • system("pause");
  • }
  • //插入书籍
  • void insert()
  • {
  • struct book *p1,*head,*p2,*p;
  • system("cls");
  • head=read();
  • p1=head;
  • p2=head->next;
  • printf("请按以下格式输入要插入的书籍信息\n");
  • printf("ISBN 分区 书名 作者 出版社 数量 单价\n");
  • p=(struct book *)malloc(sizeof(struct book));
  • scanf("%s%s%s%s%s%d%f",p->book1.isbn,p->book1.zone,p->book1.name,p->book1.author,p->book1.print,&p->book1.amount,&p->book1.price);
  • p->next=NULL;
  • /*在第一个结点插入*/
  • if(strcmp(head->book1.isbn,p->book1.isbn)>0)
  • {
  • head=p;
  • p->next=p1;
  • }
  • else
  • {
  • while(p2&&strcmp(p2->book1.isbn,p->book1.isbn)<=0)//p2为空退出循环则插入在尾部
  • {
  • p1=p2;
  • p2=p2->next;
  • }
  • p->next=p2;
  • p1->next=p;
  • }
  • printf("成功插入书籍!\n");
  • write(head);
  • display();
  • system("pause");
  • }
  • int count()//统计图书文本个数
  • {
  • FILE *fp;
  • int n=0;
  • struct book1 book1;
  • fp=fopen("","r");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • while(fscanf(fp,"%s%s%s%s%s%d%f",book1.isbn,book1.zone,book1.name,book1.author,book1.print,&book1.amount,&book1.price)!=EOF)
  • n++;
  • fclose (fp);//关闭文件
  • return n; //返回个数
  • }
  • //书籍排序功能
  • void sort()
  • {
  • FILE *fp;
  • struct book1 a[100];
  • struct book1 t; //用于排序的结构体变量
  • int n,i,j;
  • system("cls");
  • n=count();//调用统计图书文本函数
  • fp=fopen("","r");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • for(i=0;i<n;i++)//将数据复制到数组中
  • fscanf(fp,"%s%s%s%s%s%d%f",a[i].isbn,a[i].zone,a[i].name,a[i].author,a[i].print,&a[i].amount,&a[i].price);
  • /*根据isbn进行冒泡排序(升序)*/
  • for(i=0;i<n-1;i++)
  • {
  • for(j=0;j<n-1-i;j++)
  • {
  • if(strcmp(a[j].isbn,a[j+1].isbn)>0)
  • {
  • t=a[j];
  • a[j]=a[j+1];
  • a[j+1]=t;
  • }
  • }
  • }
  • fclose(fp); //注意关闭文件
  • fp=fopen("","w");
  • if(!fp)
  • {
  • printf("cannot open file\n");
  • exit(0);
  • }
  • for(i=0;i<n;i++)
  • fprintf(fp,"%-20s%-15s%-15s%-15s%-19s%-14d%-12.2f\n",a[i].isbn,a[i].zone,a[i].name,a[i].author,a[i].print,a[i].amount,a[i].price);
  • fclose(fp);
  • printf("排序成功\n");
  • display();//显示排序后的书籍
  • system("pause");
  • }
  • //借书函数
  • void lendbook()
  • {
  • struct book *head,*p;
  • char in[5][20]={'\0'};//确保最多借阅五本书
  • int flag=0;
  • int n,i;
  • system("cls");//清屏
  • display();
  • printf("请输入借书数量(注意借书数量不得超过5本):\n");
  • scanf("%d",&n);
  • printf("请输入借阅书籍编号或者书名\n");
  • head=read();
  • p=head;
  • for(i=0;i<n;i++)
  • {
  • scanf("%s",in[i]);
  • while(p)
  • {
  • if(strcmp(p->book1.isbn,in[i])==0||strcmp(p->book1.name,in[i])==0)//若满足对于书籍数量减少一本
  • {
  • p->book1.amount--;
  • flag=1;
  • break;
  • }
  • else
  • p=p->next;
  • }
  • }
  • if(flag==0)
  • printf("并没有找到此本书籍,请再次确认您的输入是否正确\n");
  • else
  • printf("借书成功!请记得按时归还书籍\n");
  • write(head);
  • }
  • //还书函数
  • void returnbook()
  • {
  • system("cls");
  • int n,i;
  • struct book *head,*p;
  • char in[5][20]={'\0'};//限制一次归还数量应小于等于5本,保证按时归还书籍
  • int flag=0;
  • head=read();
  • p=head;
  • printf("请输入还书数量(注意还书书籍不得超过五本):\n");
  • scanf("%d",&n);
  • printf("请输入归还书籍编号或者书名:\n");
  • for(i=0;i<n;i++)
  • {
  • scanf("%s",in[i]);
  • while(p)
  • {
  • if(strcmp(p->book1.isbn,in[i])==0||strcmp(p->book1.name,in[i])==0)
  • {
  • p->book1.amount++;
  • flag=1;
  • break;
  • }
  • else
  • p=p->next;
  • }
  • }
  • if(flag==0)
  • printf("输入有误请再次确认!\n");
  • else
  • printf("还书成功!\n");
  • write(head);
  • system("pause");
  • }