Linux下程序设计综合实验报告——图书管理系统(黑龙江大学)
一、系统概述
1. 开发系统的目的与意义
图书管理系统将管理人员从繁琐的工作中脱离出来,可以让图书管理员在最佳的工作状态下工作。在信息时代下,资源的合理利用很重要,而图书管理系统作为一种先进的管理技术,可以将所有资源进行分类,以便用户查阅和共享,从而提高网络信息资源的利用率。
2. 概要介绍系统
图书管理信息系统包括用户子管理系统、读者管理子系统、图书管理子系统、图书流通管理子系统,包括信息输入、信息修改、信息删除、信息显示、密码修改、借书处理和还书处理等功能。
二、系统需求分析
1. 系统工作流程、系统运行环境要求
系统工作流程为:通过用户名登录,输入密码,登陆成功后根据用户的需求来使用系统中相对应的部分。
系统运行环境为:由VMware® Workstation 16 Pro支持的Ubuntu21.04版Linux操作系统。
2. 数据的类型、值的范围及非法输入
字符串型数据范围不少于15个字节。整形数据主要用来进行功能间选择,字符串型数据用来进行具体操作。整形数据范围与int类型相同。用户名为长整形,密码为字符型,范围十五位以内。用户、读者类型为基本整型,范围八位以内。读者名、单位、联系方式、书名、作者为字符型,范围二十位以内。图书记录号、借还书数为基本整型。接受非法输入,对非法输入进行相应的提示。
三、系统概要设计
1. 数据结构设计
用户结构体包括:用户名、密码、用户类型以及自身指针。
typedef struct users
{
char uname[10];
char pword[12];
int type;
struct users *next;
}use;
读者结构体包括:读者号、读者名、读者单位信息、联系方式、可借书数、已借书数以及自身指针。
typedef struct readers
{
char readnum[15];
char rname[16];
char compory[17];
char connum[17];
int browbook;
int readbook;
struct readers *next;
}read;
图书结构体包括:记录号、书号、书名、作者、出版社、藏书量、借书量、三个指针、指向自身的指针。
typedef struct books
{
int num;
char booknum[5];
char bname[20];
char author[16];
char pubplace[16];
int total;
int borrow;
int a;
int b;
int c;
struct books *next;
}book;
图书流通结构体包括:读者号书号、借书日期、还书日期以及备注。
(1)结构体包括:书名、链表头、链表长度以及自身指针。
typedef struct titl
{
char titles[20];
int a;
int b;
struct titl *next;
}title;
(2)结构体包括:作者、链表头、链表长度以及自身指针。
typedef struct autho
{
char authors[20];
int a;
int b;
struct autho *next;
}author;
(3)结构体包括:出版社、链表头、链表长度以及自身指针。
typedef struct pubplac
{
char pubplaces[20];
int a;
int b;
struct pubplac *next;
}pubplace;
2. 软件结构设计

图1 图书管理系统软件结构
图书管理信息系统根据需求可分为:用户管理、读者管理、图书管理、图书流通管理这四个子系统。用户管理包括用户信息输入、用户信息修改、用户信息删除、用户信息显示、用户密码修改等功能。读者管理包括读者信息输入、读者信息修改、读者信息删除、读者信息按名查询等功能。图书管理包括图书信息输入、图书信息修改、图书信息查询、汇总统计等功能。图书流通管理包括借书处理和还书处理功能。用户分为:普通读者、图书管理员、系统管理员三种。普通读者只能使用“用户管理子系统”中“用户密码修改”功能和“图书管理子系统”中“图书信息查询”功能;图书管理员只能使用“图书管理子系统”和“图书流通管理子系统”;系统管理员只能使用“用户管理子系统”和“读者管理子系统”。
四、系统详细设计与实现
1. 登录模块详细设计
打开“用户文件”,读入文件内容,建立相应的链表。请用户输入用户名及密码。若用户名或密码输入不正确,最多允许尝试三次。用户名与密码输入正确时,记住当前用户类型。当该用户为“图书管理员”时,打开“图书主文件”及所有的“索引表文件”,分别将文件内容存入相应的一维数组中,打开“借还书文件”,建立相应的链表,打开“读者文件”,建立相应的链表;当该用户为系统管理员时,打开“读者文件”,读入文件内容,建立相应的链表;当该用户为“普通读者”或“系统管理员”时,打开图书主文件及所有的索引表文件,分别将文件内容读入相应的一维数组中,并关闭所有打开的文件。“普通读者”只能选“用户管理”功能项中“用户密码修改”子功能和“图书管理”子系统中“图书信息查询”子功能;“图书管理员”可以选“读者管理”、“图书管理”和“图书流通管理”功能;“系统管理员”只能选“用户管理”和“图书管理”子系统中“图书信息查询”子功能。需要根据用户类型显示相应的菜单,请用户选择功能项,或者用统一的主菜单,但不允许用户使用没有相应权限的。当退出系统时,需将各个链表和数组中的内容写回相应的文件。

图2 登录模块算法流程图

图3 登录模块效果截图
2. 读者信息显示模块详细设计
首先以图书管理员身份登录系统,选择用户信息显示功能,从读者文件中读取数据显示出全部数据,包括用户名,读者名,单位,电话,已借图书,可借图书,将读者信息按读者名姓氏排序显示,然后按回车返回。

图4 读者信息显示模块流程图

图5 读者信息显示模块效果截图
3. 读者信息修改模块详细设计
首先图书管理员输入“读者名”,系统检查是否存在该读者,若不存在,显示提示信息,并返回;若存在,则提示读者选择需要修改哪项信息,确认是否修改,若是,显示修改成功,并存入文件。

图6 读者信息修改模块算法流程



图7 读者信息修改模块效果截图
五、系统测试
1. 用户注册登录测试
在用户注册页面中,用户所要填写的注册信息包括用户名、密码等。针对用户注册的功能进行测试,对于用户注册功能模块的测试其测试用例如表1所示。
表1 用户注册的测试用例
| 测试内容 | 测试用例 | 预期结果 | 实际结果 |
| 用户名 |
| 输入成功 输入失败 输入失败 输入失败 | 与预期相同 |
| 密码 | 1.输入字母数字(6—16位)“1234567” 2.输入汉字 “拉拉aeeafdr3456” 3.输入字符少于6个或多于16个 ”sfgh” 4.不输入 | 输入成功 输入失败 输入失败 输入失败 | 与预期相同 |
2. 读者信息新建测试
在读者信息新建页面中,读者所要填写的注册信息包括用户名、单位、联系方式等。针对读者注册的功能进行测试,对于读者注册功能模块的测试其测试用例如表2所示。
表2 读者信息新建的测试用例
| 测试内容 | 测试用例 | 预期结果 | 实际结果 |
| 姓名、单位 | 1.输入字母数字 “45545adhhrgw” 2.输入汉字 “你好” 3.输入字符少于6个或多于16个 “456de” 4.不输入 | 输入成功 输入成功 输入失败 输入失败 | 与预期相同 |
| 联系方式 | 1.输入数字(6—16位)“15945944630” 2.输入汉字 “拉拉gyhjyher54586” 3.输入字符少于6个或多于16个 ”fgh56” 4.不输入 | 输入成功 输入失败 输入失败 输入失败 | 与预期相同 |
3. 借书测试
在借书测试中,读者需要先输入读者号,并输入书号检验其是否合法,然后输入借书日期。针对借书测试的功能进行测试,如表3所示。
表3借书管理的测试用例
| 测试内容 | 测试用例 | 预期结果 | 实际结果 |
| 读者号、书号 | 1.输入存在读者号或索引表中存在的书号 2.输入不存在的读者号 3.输入不存在的书号 4.不输入 | 输入成功 输入失败 输入失败 输入失败 | 与预期相同 |
| 日期 | 1.输入合法年、月、日(2020 6 1) 2输入.不合法日期(2020ab) 3.不输入 | 输入成功 输入失败 输入失败 | 与预期相同 |
六、结论
1. 完成了在Linux操作系统下图书管理系统的编写,实现了各个菜单之间的转换和系统内部的功能,实现了对用户及图书的管理和流通。
2. 系统优势在于对不同身份的用户进行了功能使用限制,避免系统混乱、越级处理等问题,可以根据用户输入的用户名确定用户的类型,并且显示不同的菜单。
3. 调试过程中遇到调试结果与预期效果不同的问题,通过重新检查相应位置代码,进行修改。
4. 我认为,开发一套系统最重要的是细心,并且思考要全面,结合实际,充分考虑到客户的需求和现实意义,在编写时要完善注释,方便其他人理解程序,做到人性化。
附录:源代码
1. 代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BACKSPACE 127
/*
函数功能:密码加密
函数入口参数:密码数组
函数返回值:密码对应字符指针
*/
char *passwordEncrypt(char password1[12])
{int i=0;system("stty -icanon");//用途:一次性读完操作,使getchar函数能够不要求回车结束输入system("stty -echo");//用途:关闭回显,使用户输入不会显示(类似终端输入密码)while(i<16){password1[i]=getchar();if(i==0&&password1[i]==BACKSPACE){i=0;password1[i]='\0';continue;}else if(password1[i]==BACKSPACE){printf("\b \b");password1[i]='\0';i=i-1;continue;}else if(password1[i]=='\n'){password1[i]='\0';break;}else{printf("*");}i++;}printf("\n");system("stty echo");//开启回显system("stty icanon");//关闭一次性读完操作,即getchar()必须回车也能获取字符return password1;
}typedef struct dat
{int year;int month;int day;
}data;/*
结构体内容:用户名 密码 类型
*/
typedef struct users
{char uname[10];char pword[12];int type;struct users *next;
}use;/*
结构体内容:读者号 读者名 读者单位 读者联系方式 可借书 一借书
*/
typedef struct readers
{char readnum[15];char rname[16];char compory[17];char connum[17];int browbook;int readbook;struct readers *next;
}read;
/*
结构体内容:记录号 书号 书名 作者 出版社 数量 借出数 指针*3
*/
typedef struct books
{int num;char booknum[5];char bname[20];char author[16];char pubplace[16];int total;int borrow;int a;int b;int c;struct books *next;
}book;
/*
结构体内容:书名 指针1 指针2
*/
typedef struct titl
{char titles[20];int a;int b;struct titl *next;
}title;
/*
结构体内容:作者 指针一 指针二
*/
typedef struct autho
{char authors[20];int a;int b;struct autho *next;
}author;
/*
结构体内容:出版社 指针一 指针二
*/
typedef struct pubplac
{char pubplaces[20];int a;int b;struct pubplac *next;
}pubplace;
/*
结构体内容:记录号 读者号 书号 借书日期 还书日期 备注
*/
typedef struct liutong
{int num;char readernum[16];char booknum[5];data borrowdata;data returndata;char tips[30];struct liutong *next;
}liutong;
//***********************************函数声明处***************************************
void menu1();
void menu2();
void menu3();
void menu4();
void menu5();
void menu6();
void menu7();
void menu8();
void userManage(use *head,char user[10]);
void userManage_pwordchange1(use *head,char uname[10]);
void userManage_input(use *head);
void userManage_change(use *head);
use *userManage_delete(use *head);
void userManage_display(use *head);
void userManage_pwordchange2(use *head,char uname[10]);
void readerManage(read *heada,use *head);
void readerManage_input(read *heada,use *head);
void readerManage_change(read *heada);
read *readerManage_delete(read *heada);
void readerManage_display(read *heada);
void readerManage_search(read *heada);
void bookManage(book *headb);
void bookManage_input(book *headb);
void bookManage_change(book *headb);
void bookManage_search(book *headb);
void bookManage_display(book *headb);
void bookManage_huizong(book *headb);
void bookliutong(book *headb,read *heada);
void bookliutong_xianshi(liutong *headc);
void bookliutong_borrow(book *headb,read *heada,liutong *headc);
void bookliutong_return(book *headb,read *heada,liutong *headc);
//***********************************************************************************
/*
函数功能:菜单
函数入口参数:无
函数返回值:图书管理系统各个选项
*/
//*************************************************************************************************
void menu1()//系统管理员需要菜单
{printf("1.用户管理\n");printf("2.图书信息查询\n");printf("3.图书汇总统计\n");printf("4.退出系统\n");
}void menu2()//图书管理员需要菜单
{printf("1.用户密码修改\n");printf("2.读者管理\n");printf("3.图书管理\n");printf("4.图书流通管理\n");printf("5.退出系统\n");
}void menu3()//普通用户需要菜单
{printf("1.用户密码修改\n");printf("2.图书信息查询\n");printf("3.图书汇总统计\n");printf("4.退出系统\n");
}void menu4()//用户管理系统菜单
{printf("1.用户信息输入\n");printf("2.用户信息修改\n");printf("3.用户信息删除\n");printf("4.用户信息显示\n");printf("5.用户密码修改\n");printf("6.返回上一页\n");printf("7.退出用户管理\n");
}void menu5()//读者管理所需菜单
{printf("1.读者信息输入\n");printf("2.读者信息修改\n");printf("3.读者信息删除\n");printf("4.读者信息查询\n");printf("5.读者信息显示\n");printf("6.返回上一页\n");printf("7.退出读者管理\n");
}void menu6()//图书管理所需菜单
{printf("1. 图书信息输入\n");printf("2. 图书信息修改\n");printf("3. 图书信息显示\n");printf("4. 图书信息查询\n");printf("5. 汇总统计\n");printf("6. 返回上一页\n");printf("7. 退出图书管理\n");
}void menu7()//查询菜单
{printf("1. 按书号查询");printf("2. 按书名查询");printf("3. 按作者查询");printf("4. 按出版社查询");printf("5. 返回主菜单");
}void menu8()//图书流通菜单
{printf("1.借书\n");printf("2.还书\n");printf("3.显示\n");printf("4.返回\n");
}
//*************************************************************************************************
void userManage(use *head,char user[10])
{FILE *fp;use *p=NULL;int n;do{menu4();printf("请输入选项:");scanf("%d",&n);switch(n){case 1:userManage_input(head);break;case 2:userManage_change(head);break;case 3:userManage_delete(head);break;case 4:userManage_display(head);break;case 5:userManage_pwordchange1(head,user);break;case 6:fp=fopen("//home//lsx2216//test2//user","w");p=head;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%s %s %d",p->uname,p->pword,p->type);fputc('\n',fp);p=p->next;}fclose(fp);return ;case 7:fp=fopen("//home//lsx2216//test2//user","w");p=head;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%s %s %d",p->uname,p->pword,p->type);fputc('\n',fp);p=p->next;}fclose(fp);exit(0);default :printf("不接受非法输入sorry\n");break;}}while(1);
}void userManage_pwordchange2(use *head,char uname[10])
{use *p=head;FILE *fp;char password[12];while(strcmp(uname,p->uname)!=0)//检测到指定位置{p=p->next;}printf("你的用户名为:%s",p->uname);printf("请在此输入新密码:(提醒:密码不要超过十二位)");scanf("%s",password);strcpy(p->pword,password);p=head;fp=fopen("user","w");fputc('\n',fp);while(p!=NULL){fprintf(fp,"%s %s %d",p->uname,p->pword,p->type);fputc('\n',fp);p=p->next;}fclose(fp);
}void userManage_input(use *head)
{use *p=NULL,*q=head;char name[10],password[12];int type;printf("请输入添加的用户名:");scanf("%s",name);p=head;while(p!=NULL){if(strcmp(name,p->uname)==0){printf("这个用户名不行,换一个吧:");scanf("%s",name);p=head;}else{p=p->next;}}printf("请输入密码:");scanf("%s",password);printf("1.系统管理员\n2.图书管理员\n3.普通用户\n请选择用户类型:");scanf("%d",&type);p=(use *)malloc(sizeof(use));strcpy(p->uname,name);strcpy(p->pword,password);p->type=type;p->next=NULL;printf("用户名:%s密码:%s类型:%d\n",p->uname,p->pword,p->type);q=head;while(q->next!=NULL){q=q->next;}q->next=p;q=head;
}void userManage_change(use *head)
{use *p=head,*temp=NULL;char user[10],password[12],name[10];int type;while(p!=NULL){printf("用户名:%s密码:%s类型:%d\n",p->uname,p->pword,p->type);p=p->next;}printf("请输入要更改的用户的用户名:");scanf("%s",user);p=head;while(1){p=head;while(strcmp(p->uname,user)!=0){p=p->next;if(p==NULL){break;}}if(p==NULL){printf("请重新输入要更改的用户的用户名:");scanf("%s",user);p=head;}else{break;}}printf("%s %s %d",p->uname,p->pword,p->type);printf("请为此用户输入新的用户名:");scanf("%s",name);while(1){temp=head;while(strcmp(temp->uname,name)!=0){temp=temp->next;if(temp==NULL){break;}}if(temp==NULL){break;}else{printf("用户名不能重复,请输入新的用户名:");scanf("%s",name);}}printf("请输入密码:");scanf("%s",password);printf("1.系统管理员\n2.图书管理员\n3.普通用户\n请选择用户类型:");scanf("%d",&type);strcpy(p->uname,name);strcpy(p->pword,password);p->type=type;printf("更改为:用户名:%s密码:%s类型:%d\n",p->uname,p->pword,p->type);}void userManage_display(use *head)
{use *p=NULL;p=head;while(p!=NULL){printf("用户名:%s密码:%s类型:%d\n",p->uname,p->pword,p->type);p=p->next;}
}use *userManage_delete(use *head)
{char name[10];use *p=NULL,*temp=NULL;p=head;while(p!=NULL){printf("用户名:%s密码:%s类型:%d\n",p->uname,p->pword,p->type);p=p->next;}printf("请输入需要删除的用户名:");scanf("%s",name);p=head;while(strcmp(name,p->uname)!=0&&p!=NULL){temp=p;p=p->next;if(p==NULL){printf("好像没有这个用户名\n");}}if(p==NULL){printf("好像没有这个用户名\n");}if(strcmp(name,p->uname)==0){if(p==head){head=p->next;}else{temp->next=p->next;}return head;}
}void userManage_pwordchange1(use *head,char uname[10])
{use *p=head;char password[12];while(strcmp(uname,p->uname)!=0)//检测到指定位置{p=p->next;}printf("你的用户名为:%s",p->uname);printf("请在此输入新密码:(提醒:密码不要超过十二位)");scanf("%s",password);strcpy(p->pword,password);
}void readerManage(read *heada,use *head)
{int n;FILE *fp;read *p,*temp;while(1){menu5();printf("请输入选项:");scanf("%d",&n);switch(n){case 1:readerManage_input(heada,head);break;case 2:readerManage_change(heada);break;case 3:readerManage_delete(heada);break;case 4:readerManage_search(heada);break;case 5:readerManage_display(heada);break;case 6:fp=fopen("//home//liuhe//test//reader","w");p=heada;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%s %s %s %s %d %d",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);fputc('\n',fp);p=p->next;}fclose(fp);return;case 7:fp=fopen("//home//liuhe//test//reader","w");p=heada;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%s %s %s %s %d %d",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);fputc('\n',fp);p=p->next;}fclose(fp);exit(0);default :printf("不接受非法输入\n");break;}}
}void readerManage_input(read *heada,use *head)
{read *p=NULL,*q=heada;use *pa=NULL;char readnum[10],rname[15],compory[15],connum[14];int browbook,readbook,a,b=0,c=0;printf("请输入添加的读者号:");pa=head;p=heada;while(scanf("%s",readnum)!=EOF){b=0;pa=head;while(pa!=NULL){if(strcmp(pa->uname,readnum)==0){b++;break;}pa=pa->next;}if(b==0){printf("此用户名不存在,无法添加其读者信息,请重新输入\n");}else{c=0;p=heada;while(p!=NULL){if(strcmp(p->readnum,readnum)==0){c++;break;}p=p->next;}if(c!=0){printf("用户名重复,请重新输入:\n");}else{break;}}}printf("请输入读者名:");scanf("%s",rname);printf("请输入读者所在单位:");scanf("%s",compory);printf("请输入读者联系方式:");scanf("%s",connum);a=strlen(readnum);if(a==7){browbook=10;}else if(a==8){browbook=5;}else{browbook=10;}while(1){printf("请输入读者借书情况:");scanf("%d",&readbook);if(readbook>browbook){printf("不能超过最大数目");}else{break;}}p=(read *)malloc(sizeof(read));strcpy(p->readnum,readnum);strcpy(p->rname,rname);strcpy(p->compory,compory);strcpy(p->connum,connum);p->browbook=browbook;p->readbook=readbook;if(heada==NULL){heada=p;printf("233=读者号:%s 读者名:%s 读者单位:%s 读者联系方式:%s 读者可借阅数目:%d 读者已借阅数目:%d\n",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);}else{q=heada;while(q->next!=NULL){q=q->next;}q->next=p;q=heada;}printf("读者号:%s 读者名:%s 读者单位:%s 读者联系方式:%s 读者可借阅数目:%d 读者已借阅数目:%d\n",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);
}void readerManage_change(read *heada)
{read *p=heada,*temp=NULL;char readnum[10],rname[12],compory[17],connum[13];int n,a;while(p!=NULL){printf("读者号:%s 读者名:%s 读者单位:%s 读者联系方式:%s 读者可借阅数目:%d 读者已借阅数目:%d\n",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);p=p->next;}printf("请输入要更改的读者号:");scanf("%s",readnum);p=heada;while(1){p=heada;while(strcmp(p->readnum,readnum)!=0){p=p->next;if(p==NULL){break;}}if(p==NULL){printf("请重新输入要更改的用户的用户名:");scanf("%s",readnum);p=heada;}else{break;}}printf("读者号:%s 读者名:%s 读者单位:%s 读者联系方式:%s 读者可借阅数目:%d 读者已借阅数目:%d\n",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);while(1){printf("1.读者名更改\n2.读者单位更改\n3.读者联系方式更改\n4.读者可借书数更改\n5.退出更改\n请输入更改选项");scanf("%d",&n);switch(n){case 1:printf("请输入新的读者名:");scanf("%s",rname);strcpy(p->rname,rname);break;case 2:printf("请输入新的单位:");scanf("%s",compory);strcpy(p->compory,compory);break;case 3:printf("请输入新的读者联系方式:");scanf("%s",connum);strcpy(p->connum,connum);break;case 4:printf("请输入更改后的已借书数量:");while(scanf("%d",&a)!=EOF){if(p->browbook<=a){printf("%d已经超过最大数量,请重新输入:",p->browbook);continue;}else{p->readbook=a;break;}}break;case 5:return;break;default :printf("不接受非法输入");break;}}
}read *readerManage_delete(read *heada)
{char readnum[10];read *p=heada,*temp=NULL;readerManage_display(heada);printf("请输入需要删除的读者号:");scanf("%s",readnum);p=heada;while(strcmp(readnum,p->readnum)!=0&&p!=NULL){temp=p;p=p->next;if(p==NULL){printf("好像没有这个用户名\n");}}if(p==NULL){printf("好像没有这个用户名\n");}if(strcmp(readnum,p->readnum)==0){if(p==heada){heada=p->next;}else{temp->next=p->next;}return heada;}
}void readerManage_search(read *heada)
{read *p=heada;char readnum[18];printf("请输入读者姓名:");scanf("%s",readnum);while(p!=NULL){if(strcmp(p->rname,readnum)==0){printf("读者号:%s 读者名:%s 读者单位:%s 读者联系方式:%s 读者可借阅数目:%d 读者已借阅数目:%d\n",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);return;}else{p=p->next;}}printf("没找到\n");
}void readerManage_display(read *heada)
{read *p;p=heada;while(p!=NULL){printf("%s %s %s %s %d %d\n",p->readnum,p->rname,p->compory,p->connum,p->browbook,p->readbook);p=p->next;}return;
}void bookManage(book *headb)
{book *p=NULL,*t=NULL;FILE *fp;int n;while(1){menu6();printf("请输入想要的功能:");scanf("%d",&n);switch(n){case 1:bookManage_input(headb);break;case 2:bookManage_change(headb);break;case 3:bookManage_display(headb);break;case 4:bookManage_search(headb);break;case 5:bookManage_huizong(headb);break;case 6:fp=fopen("//home//liuhe//test//book","w");p=headb;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%d %s %s %s %s %d %d %d %d %d",p->num,p->booknum,p->bname,p->author,p->pubplace,p->total,p->borrow,p->a,p->b,p->c);fputc('\n',fp);p=p->next;}fclose(fp);return;case 7:fp=fopen("//home//liuhe//test//book","w");p=headb;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%d %s %s %s %s %d %d %d %d %d",p->num,p->booknum,p->bname,p->author,p->pubplace,p->total,p->borrow,p->a,p->b,p->c);fputc('\n',fp);p=p->next;}fclose(fp);exit(0);default :printf("不接受非法输入");break;}}
}void bookManage_input(book *headb)
{int i=1;FILE *fp;book *p,*t,*o;title *headc=NULL,*a,*d;author *headd=NULL,*b,*e;pubplace *heade=NULL,*c,*f;fp=fopen("//home//liuhe//test//bookname","r");while(!feof(fp)){a=(title *)malloc(sizeof(title));if(EOF==fscanf(fp,"%s %d %d",a->titles,&a->a,&a->b)){break;}a->next=NULL;if(headc==NULL){headc=a;}else{d=headc;while(d->next!=NULL){d=d->next;}d->next=a;}}fclose(fp);fp=fopen("//home//liuhe//test//bookauthor","r");while(!feof(fp)){b=(author *)malloc(sizeof(author));if(EOF==fscanf(fp,"%s %d %d",b->authors,&b->a,&b->b)){break;}b->next=NULL;if(headd==NULL){headd=b;}else{e=headd;while(e->next!=NULL){e=e->next;}e->next=b;}}fclose(fp);fp=fopen("//home//liuhe//test//bookpublic","r");while(!feof(fp)){c=(pubplace *)malloc(sizeof(pubplace));if(EOF==fscanf(fp,"%s %d %d",c->pubplaces,&c->a,&c->b)){break;}c->next=NULL;if(heade==NULL){heade=c;}else{f=heade;while(f->next!=NULL){f=f->next;}f->next=c;}}fclose(fp);p=headb;while(p->next!=NULL){p=p->next;i++;}t=(book *)malloc(sizeof(book));t->num=(i+1);p=headb;printf("请输入新添加的书号:");scanf("%s",t->booknum);while(p!=NULL){if(strcmp(p->booknum,t->booknum)==0){printf("重复了,请重新输入:");scanf("%s",t->booknum);p=headb;}else{p=p->next;}}printf("请输入这本书的书名:");scanf("%s",t->bname);printf("请输入这本书的作者:");scanf("%s",t->author);printf("请输入这本书的出版社:");scanf("%s",t->pubplace);printf("请输入这本书的藏书量:");scanf("%d",&t->total);printf("请输入这本书的借出量:");scanf("%d",&t->borrow);a=headc;while(a!=NULL){if(strcmp(a->titles,t->bname)==0){t->a=a->a;//精髓a->a=t->num;a->b++;break;}else{a=a->next;}}if(a==NULL){t->a=0;a=headc;d=(title *)malloc(sizeof(title));d->next=NULL;strcpy(d->titles,t->bname);d->a=t->num;d->b=1;while(a->next!=NULL){a=a->next;}a->next=d;}b=headd;while(b!=NULL){if(strcmp(b->authors,t->author)==0){t->b=b->a;//精髓b->a=t->num;b->b++;break;}else{b=b->next;}}if(b==NULL){t->b=0;b=headd;e=(author *)malloc(sizeof(author));e->next=NULL;strcpy(e->authors,t->author);e->a=t->num;e->b=1;while(b->next!=NULL){b=b->next;}b->next=e;}c=heade;while(c!=NULL){if(strcmp(c->pubplaces,t->pubplace)==0){t->c=c->a;//精髓c->a=t->num;c->b++;break;}else{c=c->next;}}if(c==NULL){t->c=0;c=heade;f=(pubplace *)malloc(sizeof(pubplace));f->next=NULL;strcpy(f->pubplaces,t->pubplace);f->a=t->num;f->b=1;while(c->next!=NULL){c=c->next;}c->next=e;}printf("%d %s %s %s %s %d %d %d %d %d\n",t->num,t->booknum,t->bname,t->author,t->pubplace,t->total,t->borrow,t->a,t->b,t->c);t->next=NULL;p=headb;while(p->next!=NULL){p=p->next;}p->next=t;p=headb;a=headc;b=headd;c=heade;fp=fopen("//home//liuhe//test//book","w");p=headb;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%d %s %s %s %s %d %d %d %d %d",p->num,p->booknum,p->bname,p->author,p->pubplace,p->total,p->borrow,p->a,p->b,p->c);fputc('\n',fp);p=p->next;}fclose(fp);fp=fopen("//home//liuhe//test//bookname","w");a=headc;fputc('\n',fp);while(a!=NULL){fprintf(fp,"%s %d %d",a->titles,a->a,a->b);fputc('\n',fp);a=a->next;}fclose(fp);fp=fopen("//home//liuhe//test//bookauthor","w");b=headd;fputc('\n',fp);while(b!=NULL){fprintf(fp,"%s %d %d",b->authors,b->a,b->b);fputc('\n',fp);b=b->next;}fclose(fp);fp=fopen("//home//liuhe//test//bookpublic","w");c=heade;fputc('\n',fp);while(c!=NULL){fprintf(fp,"%s %d %d",c->pubplaces,c->a,c->b);fputc('\n',fp);c=c->next;}fclose(fp);}void bookManage_change(book *headb)
{int n,a;book *p=headb;char booknum[5];printf("请输入想要更改的书的书号:");scanf("%s",booknum);while(p!=NULL){if(strcmp(p->booknum,booknum)==0){printf("已经找到这本书\n");break;}else{p=p->next;}}if(p==NULL){printf("没有找到这个书号\n");return ;}while(1){printf("1.藏书量\n2.借书数\n3.退出\n请输入你想要修改的项:");scanf("%d",&n);switch(n){case 1:printf("\n请输入数量;");scanf("%d",&a);p->total=a;break;case 2:printf("\n请输入数量:");scanf("%d",&a);if(p->total<a){printf("输入错误");}else{p->borrow=a;}break;case 3:return;default:printf("不接受其他输入");break;}}}void bookManage_search(book *headb)
{int n,i,o,p,q,r,s;FILE *fp;book *l;l=headb;while(l->next!=NULL){l=l->next;}s=l->num;s++;book a[s];title b[10];author c[10];pubplace d[10];char input[20];i=1;fp=fopen("//home//liuhe//test//book","r");while(!feof(fp)){if(EOF==fscanf(fp,"%d%s%s%s%s%d%d%d%d%d",&a[i].num,a[i].booknum,a[i].bname,a[i].author,a[i].pubplace,&a[i].total,&a[i].borrow,&a[i].a,&a[i].b,&a[i].c));{;}i++;}o=i-2;fclose(fp);i=1;fp=fopen("//home//liuhe//test//bookname","r");while(!feof(fp)){if(EOF==fscanf(fp,"%s%d%d",b[i].titles,&b[i].a,&b[i].b)){break;}i++;}p=i-1;fclose(fp);i=1;fp=fopen("//home//liuhe//test//bookauthor","r");while(!feof(fp)){if(EOF==fscanf(fp,"%s%d%d",c[i].authors,&c[i].a,&c[i].b)){break;}i++;}q=i-1;fclose(fp);i=1;fp=fopen("//home//liuhe//test//bookpublic","r");while(!feof(fp)){if(EOF==fscanf(fp,"%s%d%d",d[i].pubplaces,&d[i].a,&d[i].b)){break;}i++;}r=i-1;fclose(fp);while(1){printf("1.按书号查询\n2.按书名查询\n3.按作者查询\n4.按出版社查询\n5.退出\n请输入查询方式:");scanf("%d",&n);switch(n){case 1:printf("请输入想要查询的书号:");scanf("%s",input);i=1;while(strcmp(a[i].booknum,input)!=0){i++;if(i>o){break;}}if(i>o){printf("没有此书号\n");break;}else{printf("%d %s %s %s %s %d %d %d %d %d\n",a[i].num,a[i].booknum,a[i].bname,a[i].author,a[i].pubplace,a[i].total,a[i].borrow,a[i].a,a[i].b,a[i].c);}break;case 2:printf("请输入查询的书名:");scanf("%s",input);i=1;while(strcmp(b[i].titles,input)!=0){i++;if(i>p){break;}}if(i>p){printf("没有找到");break;}else{i=b[i].a;while(i!=0){printf("%d %s %s %s %s %d %d %d %d %d\n",a[i].num,a[i].booknum,a[i].bname,a[i].author,a[i].pubplace,a[i].total,a[i].borrow,a[i].a,a[i].b,a[i].c);i=a[i].a;}}break;case 3:printf("请输入查询的作者名字:");scanf("%s",input);i=1;while(strcmp(c[i].authors,input)!=0){i++;if(i>q){break;}}if(i>q){printf("没有找到");break;}else{i=c[i].a;while(i!=0){printf("%d %s %s %s %s %d %d %d %d %d\n",a[i].num,a[i].booknum,a[i].bname,a[i].author,a[i].pubplace,a[i].total,a[i].borrow,a[i].a,a[i].b,a[i].c);i=a[i].b;}}break;case 4:printf("请输入查询的出版社:");scanf("%s",input);i=1;while(strcmp(d[i].pubplaces,input)!=0){i++;if(i>r){break;}}if(i>r){printf("没有找到");break;}else{i=d[i].a;while(i!=0){printf("%d %s %s %s %s %d %d %d %d %d\n",a[i].num,a[i].booknum,a[i].bname,a[i].author,a[i].pubplace,a[i].total,a[i].borrow,a[i].a,a[i].b,a[i].c);i=a[i].c;}}break;case 5:return;default:printf("没有此选项\n");break;}}
}void bookManage_display(book *headb)
{book *p;p=headb;while(p!=NULL){printf("%d %s %s %s %s %d %d %d %d %d\n",p->num,p->booknum,p->bname,p->author,p->pubplace,p->total,p->borrow,p->a,p->b,p->c);p=p->next;}
}void bookManage_huizong(book *headb)
{book *p=headb,*t=NULL,*o=NULL;int a=0,b=0;while(p!=NULL){if(p->total>a){a=p->total;t=p;}if(p->borrow>b){b=p->borrow;o=p;}p=p->next;}p=headb;while(p!=NULL){if(p->total==a){printf("藏书最多的有书号:%s书名:%s作者:%s出版社:%s藏书数:%d\n",p->booknum,p->bname,p->author,p->pubplace,p->total);}p=p->next;}p=headb;while(p!=NULL){if(p->borrow==b){printf("热门的有书号:%s书名:%s作者:%s出版社:%s借出数:%d\n",p->booknum,p->bname,p->author,p->pubplace,p->borrow);}p=p->next;}return;
}void bookliutong(book *headb,read *heada)
{int n;FILE *fp;liutong *p,*headc=NULL,*t=NULL;fp=fopen("//home//liuhe//test//bookliutong","r");while(!feof(fp)){p=(liutong *)malloc(sizeof(liutong));p->next=NULL;if(EOF==fscanf(fp,"%d %s %s %d/%d/%d %d/%d/%d %s",&p->num,p->readernum,p->booknum,&p->borrowdata.year,&p->borrowdata.month,&p->borrowdata.day,&p->returndata.year,&p->returndata.month,&p->returndata.day,p->tips)){break;}if(headc==NULL){headc=p;}else{t=headc;while(t->next!=NULL){t=t->next;}t->next=p;}}fclose(fp);while(1){menu8();printf("请输入选项:");scanf("%d",&n);switch(n){case 1:bookliutong_borrow(headb,heada,headc);break;case 2:bookliutong_return(headb,heada,headc);break;case 3:bookliutong_xianshi(headc);break;case 4:return;break;default:printf("没有这个选项\n");break;}}
}
void bookliutong_xianshi(liutong *headc)
{liutong *p=headc;while(p!=NULL){printf("%d %s %s %d/%d/%d %d/%d/%d %s\n",p->num,p->readernum,p->booknum,p->borrowdata.year,p->borrowdata.month,p->borrowdata.day,p->returndata.year,p->returndata.month,p->returndata.day,p->tips);p=p->next;}
}
void bookliutong_borrow(book *headb,read *heada,liutong *headc)
{int a,n;long int s,l;FILE *fp;liutong *p,*t=headc;book *q=headb;read *w=heada;p=(liutong *)malloc(sizeof(liutong));p->next=NULL;char number1[30],number2[30];while(t->next!=NULL){t=t->next;}a=t->num;t=headc;printf("请输入读者号:");scanf("%s",number1);printf("请输入书号:");scanf("%s",number2);while(w!=NULL){if(strcmp(number1,w->readnum)==0){break;}w=w->next;}if(w==NULL){printf("没有此读者\n");return;}else{while(q!=NULL){if(strcmp(number2,q->booknum)==0){break;}q=q->next;}if(q==NULL){printf("没有找到此书号\n");return;}else{if(w->readbook>=w->browbook){printf("读者不能在借书了\n");return;}if(q->borrow>=q->total){printf("书已经借完了\n");return;}w->readbook++;q->borrow++;p->num=a+1;strcpy(p->readernum,number1);strcpy(p->booknum,number2);printf("请输入借书日期:");scanf("%d%d%d",&p->borrowdata.year,&p->borrowdata.month,&p->borrowdata.day);s=p->borrowdata.year*365+(p->borrowdata.month-1)*30+p->borrowdata.day;p->returndata.year=0;p->returndata.month=0;p->returndata.day=0;strcpy(p->tips,"noreturn");t=headc;while(t->next!=NULL){t=t->next;}t->next=p;}}//printf("%d %s %s %d/%d/%d %d/%d/%d %s",p->num,p->readernum,p->booknum,p->borrowdata.year,p->borrowdata.month,p->borrowdata.day,p->returndata.year,p->returndata.month,p->returndata.day,p->tips);fp=fopen("//home//liuhe//test//reader","w");w=heada;fputc('\n',fp);while(w!=NULL){fprintf(fp,"%s %s %s %s %d %d",w->readnum,w->rname,w->compory,w->connum,w->browbook,w->readbook);fputc('\n',fp);w=w->next;}fclose(fp);fp=fopen("//home//liuhe//test//book","w");q=headb;fputc('\n',fp);while(q!=NULL){fprintf(fp,"%d %s %s %s %s %d %d %d %d %d",q->num,q->booknum,q->bname,q->author,q->pubplace,q->total,q->borrow,q->a,q->b,q->c);fputc('\n',fp);q=q->next;}fclose(fp);fp=fopen("//home//liuhe//test//bookliutong","w");p=headc;while(p!=NULL){fprintf(fp,"%d %s %s %d/%d/%d %d/%d/%d %s",p->num,p->readernum,p->booknum,p->borrowdata.year,p->borrowdata.month,p->borrowdata.day,p->returndata.year,p->returndata.month,p->returndata.day,p->tips);fputc('\n',fp);p=p->next;}fclose(fp);
}void bookliutong_return(book *headb,read *heada,liutong *headc)
{int a;long int s,l;FILE *fp;liutong *p,*t=headc;book *q=headb;read *w=heada;char number1[30],number2[30],returndata[30],tips[30];printf("请输入读者号:");scanf("%s",number1);printf("请输入书号:");scanf("%s",number2);while(w!=NULL){if(strcmp(number1,w->readnum)==0){break;}w=w->next;}if(w==NULL){printf("没有此读者\n");return;}else{while(q!=NULL){if(strcmp(number2,q->booknum)==0){break;}q=q->next;}if(q==NULL){printf("没有找到此书号\n");return;}else{p=headc;while(p!=NULL){if(strcmp(p->readernum,number1)==0){if(strcmp(p->booknum,number2)==0){if(strcmp(p->tips,"noreturn")==0){break;}else{p=p->next;continue;}}else{p=p->next;continue;}}else{p=p->next;continue;}}if(p==NULL){printf("????");return;}else{s=(p->borrowdata.year)*365+(p->borrowdata.month-1)*30+p->borrowdata.day;printf("请输入还书日期:");while(scanf("%d%d%d",&p->returndata.year,&p->returndata.month,&p->returndata.day)){l=(p->returndata.year)*365+(p->returndata.month-1)*30+p->returndata.day;if(l<s){printf("请重新输入:");}else{break;}}strcpy(p->tips,"return");q->borrow--;w->readbook--;}}}fp=fopen("//home//liuhe//test//reader","w");w=heada;fputc('\n',fp);while(w!=NULL){fprintf(fp,"%s %s %s %s %d %d",w->readnum,w->rname,w->compory,w->connum,w->browbook,w->readbook);fputc('\n',fp);w=w->next;}fclose(fp);fp=fopen("//home//liuhe//test//book","w");q=headb;fputc('\n',fp);while(q!=NULL){fprintf(fp,"%d %s %s %s %s %d %d %d %d %d",q->num,q->booknum,q->bname,q->author,q->pubplace,q->total,q->borrow,q->a,q->b,q->c);fputc('\n',fp);q=q->next;}fclose(fp);fp=fopen("//home//liuhe//test//bookliutong","w");p=headc;fputc('\n',fp);while(p!=NULL){fprintf(fp,"%d %s %s %d/%d/%d %d/%d/%d %s",p->num,p->readernum,p->booknum,p->borrowdata.year,p->borrowdata.month,p->borrowdata.day,p->returndata.year,p->returndata.month,p->returndata.day,p->tips);fputc('\n',fp);p=p->next;}fclose(fp);//printf("\n");
}
/*
函数功能:完成登陆
函数入口参数:无
函数返回值:具体情况决定传参
*/
void logIN()
{int i=0,n,a=0;use *head=NULL,*p,*q,*temp;read *heada=NULL,*t,*o,*u;book *headb=NULL,*k,*l,*m;FILE *fp;char name[10],password[12];fp=fopen("//home//liuhe//test//user","r");while(!feof(fp)){p=(use *)malloc(sizeof(use));fscanf(fp,"%s %s %d",p->uname,p->pword,&p->type);p->next=NULL;if(head==NULL){head=p;}else{q=head;while(q->next!=NULL){q=q->next;}q->next=p;}}fclose(fp);//将文件内用户信息加入链表中fp=fopen("//home//liuhe//test//book","r");while(!feof(fp)){k=(book *)malloc(sizeof(book));if(EOF==fscanf(fp,"%d%s %s %s %s %d%d%d%d%d",&k->num,k->booknum,k->bname,k->author,k->pubplace,&k->total,&k->borrow,&k->a,&k->b,&k->c)){break;}k->next=NULL;if(headb==NULL){headb=k;}else{l=headb;while(l->next!=NULL){l=l->next;}l->next=k;}}fclose(fp);q=head;temp=NULL;while(q->next!=NULL){temp=q;q=q->next;if(q->type==0){temp->next=NULL;}}printf("请输入用户名:");scanf("%s",name);temp=NULL;p=head;while(i<3){if(strcmp(p->uname,name)==0){printf("请输入密码:");if(i==0){getchar();}passwordEncrypt(password);if(strcmp(p->pword,password)==0){printf("登陆成功,您的用户类型为:");if(p->type==1){printf("系统管理员\n");}if(p->type==2){printf("图书管理员\n");}if(p->type==3){printf("普通读者\n");}if(p->type==1){while(1){menu1();printf("请输入你的选择:");scanf("%d",&n);if(n==1){userManage(head,p->uname);}else if(n==2){bookManage_search(headb);}else if(n==3){bookManage_display(headb);}else if(n==4){return;}else{printf("不接受非法输入\n");}}}if(p->type==2){fp=fopen("//home//liuhe//test//reader","r");while(!feof(fp)){t=(read *)malloc(sizeof(read));if(EOF==fscanf(fp,"%s %s %s %s %d %d",t->readnum,t->rname,t->compory,t->connum,&t->browbook,&t->readbook)){break;}t->next=NULL;if(heada==NULL){heada=t;}else{u=heada;while(u->next!=NULL){u=u->next;}u->next=t;}}fclose(fp);while(1){menu2();printf("请输入你的选择:");scanf("%d",&n);if(n==1){userManage_pwordchange2(head,p->uname);}else if(n==2){readerManage(heada,head);}else if(n==3){bookManage(headb);}else if(n==4){bookliutong(headb,heada);}else if(n==5){return;}else{printf("不接受非法输入\n");}}}if(p->type==3){menu3();while(1){printf("请输入你的选择:");scanf("%d",&n);if(n==1){userManage_pwordchange2(head,p->uname);}else if(n==2){bookManage_search(headb);}else if(n==3){bookManage_display(headb);}else if(n==4){return;}else{printf("不接受非法输入\n");}}}break;}else{printf("密码错误");i++;}}else{p=p->next;}if(p->uname==NULL){printf("用户名错误,清重新输入:");scanf("%s",name);p=head;i++;}}if(i==3){printf("\n您的错误次数过多,已退出");exit(0);}
}int main()
{logIN();return 0;
}
2. 相关文件
book
1 1021 数据库 杨艳 人民邮电 10 7 0 0 0
2 1014 数据结构 赵鹏 高等教育 9 7 0 0 0
3 1106 操作系统 金虎 人民邮电 8 6 0 0 1
4 1108 数据结构 高扬 清华大学 7 5 2 0 0
5 1203 程序设计 杨艳 高等教育 9 4 0 1 2
6 2105 数据库 金虎 清华大学 7 3 1 3 4
7 1012 数据结构 杨艳 人民邮电 8 2 4 5 3
8 0109 程序设计 赵鹏 清华大学 9 1 5 2 6
9 1024 数据库 金虎 人民邮电 40 10 6 6 7
10 2002 数据库 拉萨新 欸黑 40 12 9 0 0
bookauthor
杨艳 7 3
赵鹏 8 2
金虎 9 3
高扬 4 1
拉萨新 10 1
bookliutong
1 1998017 1021 2019/3/21 2019/4/15 return
2 2001021 1014 2019/3/25 0/0/0 noreturn
3 1988003 1106 2019/3/28 2019/4/15 return
4 20172568 1108 2019/4/1 2019/4/8 return
5 2001021 1024 1999/20/30 2000/21/20 return
6 2001021 1021 2000/2/13 2000/2/14 return
7 2001021 2002 2020/2/1 2021/3/1 return
bookname
数据库 10 4
数据结构 7 3
操作系统 3 1
程序设计 8 2
bookpublic
人民邮电 9 4
高等教育 5 2
清华大学 8 3
拉萨新 10
reader
1998017 丁一 网络中心 13945092233 10 5
2001021 王二 图书馆 13145092236 10 3
1988003 张三 计算机学院 13745092237 10 8
20172568 李四 软件学院 13945092239 5 3
user
1998017 1234567q 1
2001021 S1234567 2
1988003 123W5678 3
20172568 ZZ123qq9 3
20215031 123456 3
3. 注意
由于时间太久,不方便复现Linux下的操作流程,代码不确定完整且成功运行,有条件有能力的同志,若能发现并解决问题,希望在评论区指导一下他人,有写的比这个好的欢迎留下分享链接。
若觉得有帮助,欢迎点赞关注,一起成长进步~
声明:本文仅供学习交流,禁作商用;禁篡改、歪曲及有偿传播,引用需标明来源。侵权必究。
