图书管理信息系统
一、 课程设计题目:图书管理信息系统
二、课程设计内容:
实现图书管理信息系统的设计。这是一个数据结构的综合使用,涉及的知识比较全面,
特别是对文件的使用更为全面。
进入系统后,操作员可进行系统维护、读者管理、图书管理、图书流通、退出系统等
操作。
系统维护:有“初始化”和“读盘”两个重要操作。第一次开始运行时,必须选择“初
始化”,使有关文件指针、计数器等初始化为 0;而在以后的每次操作开始时,选择“读盘”,
将保存过的相关图书信息磁盘文件读入,以便进行各类操作。
读者管理:可实现读者信息的追加一项输入。需要输入读者号、读者名、可借书数。
输入“y”可连续输入信息,若输入“n”则结束输入,退出读者管理。
图书管理:有“图书信息输入”和“图书信息查询”两个重要操作。若选“图书信息
输入”,就进入相关子模块,在输入信息的同时建立相应的索引及索引文件和索引链头文件,
输入书号、书名、作者名、出版社、分类号、藏书量等信息,根据提示输入“y”实现连续
输入,若输入“n”则结束输入,退出图书管理;有了图书信息数据之后,就可以进行图书
信息的查询以及图书借阅等操作了。若选“图书信息查询”,可根据提示按书号、书名、作
者、出版社等进行查询,系统会将查询结果输出。
图书流通:有“借书处理”和“还书处理”两个重要操作。当选择“借书处理”,系
统接受输入信息后,首先查询读者文件。若没查到,显示“非法读者!”,若查到,则再检查
该读者书是否已借满,如果未借满,则继续检查图书文件;否则显示“书已借满!”。检查图
书文件如发现书号不存在或书已借出,都会提示读者“非法书号!”或“书已借出”,否则,
进行借出处理,修改借阅文件、读者文件以及图书主文件的相关数据项,并显示“借书成功!”。
当选择“还书处理”,系统在接受输入信息之后,首先用书号查询借还书文件,若找到,则
填入还书日期,然后再用书号查询图书主文件,修改借出数,用读者号查找读者文件,修改
读者的借书数,而后显示“还书成功!”,否则显示“非法书号!”并返回主控菜单。
退出系统:当需要的操作完成后,选择该项,系统会自动将当前图书数据及相关的
信息写入磁盘文件。待下次运行系统时,首先读入文件,再进行各种操作。
三、算法设计:
对于主关键字的查找,采取折半查找的算法,对于次关键字的查找,采取顺序查找
的算法。
存储用到了静态链表和文件操作。
四、程序正确性验证(指边界测试数据,即程序对于精心选择的典型、苛刻而带有刁难性的
(4)当借书时输入无效的书号时:
(5)当还书时输入错误的书号时:
五、课程设计过程中出现的主要问题、原因及解决方法:
出现的主要问题是:当连续输入三个字符串时,第二个字符串不能传入变量中;
原因:第一个字符数组的长度定义的有问题。
解决方法:让三个字符串分开输入,将第一个字符数组的长度加 1。
出现的问题还有,就是对 scanf 和 prinf 的用法不熟。
六、 课程设计的主要收获:
通过这次课程设计,我对学过的知识进行了综合,一些理解的不够深刻的问题,能
得以解决。从碰到问题,在网上找资料,从图书馆借相关书籍看,请同学和老师帮忙,到
真正解决问题,我经历了,从痛苦到喜悦的全过程。
这次课程设计给我更多的,我想还是那份编程的经验与其过程中的酸甜苦辣。
同时很感谢帮助过我的同学,更感谢胡老师的悉心教导。
七、 对今后课程设计的建议:
希望老师在验收时,不要盲目的相信学生,也不要怀疑学生,仅此而已。
八、源代码
/*borrow.c*//*(1)借书处理算法*/
void BorrowBook(BookDbaseFile &bf,BnoIdxFile bif,BbookFile &bbf,ReadFile &rf)
{
char a[5]; int i,j,k=0,jls=0;
char dzh[4],sh[5],jyrq[8];
cout<<"输入读者号:"; cin>>dzh;
for(i=1;i<=rf.len;i++)
}
k=i; break;
//查找读者文件
if(strcmp(dzh,rf.ReadRec[i].rno)==0)
{
if(k==0)
{
if(rf.ReadRec[k].bn2>=rf.ReadRec[k].bn1)
{
printf("书已借满!\n");return;
printf("非法读者!\n");
return;
}
}
cout<<"输入书号:";
strcpy(a,sh);
cin>>sh;
//查找图书文件
j=BinSearch(bif,sh);
if(j==0)
{
printf("非法书号!\n");
return;
}
if(bf.BookDbase[j].borrownum>=bf.BookDbase[j].storenum)
{
printf("图书已借出\n");
return;
}
//借还书文件追加一条记录,记录相关内容
cin>>jyrq;
//借还书文件记录数加 1
cout<<"输入借书日期:";
jls=++bbf.len;
strcpy(bbf.Bbook[jls].rno,dzh);
strcpy(bbf.Bbook[jls].bno,a);
rf.ReadRec[k].bn2++;
cout<<"该读者现在已借书数:"<
//查找图书文件
if(m==0){printf("书号有误,不是该读者所借的书的书号!\n");return;}
j=BinSearch(bif,sh);
if(j==0){printf("非法书号!\n");return;}
cout<<"输入还书日期:";
rf.ReadRec[k].bn2--;
bf.BookDbase[j].borrownum--;
strcpy(bbf.Bbook[m].date2,hsrq);
scanf("%s",hsrq);
//修改借书数
//修改借出数
//填入还书日期 printf("还书成功!\n"); }
/*createfile.c 输入图书记录建立相关文件*/
/*(1)追加一条图书主数据库记录*/
void AppeDBaseRec(BookDbaseFile &df)
{
//图书主数据库长度加 1
作者名 出版社 分类 藏书量\n");
int i; i=++df.len;
printf("书号 书 名
scanf("%s%s",df.BookDbase[i].bno,df.BookDbase[i].bname);
scanf("%s%s",df.BookDbase[i].author,df.BookDbase[i].press);
scanf("%s %d",df.BookDbase[i].sortno,&df.BookDbase[i].storenum);
df.BookDbase[i].borrownum=0;
for(int j=1;j=1)
{
if(strcmp(sh,bif.BnoIdx[j].bno)>0)
{k=j+1;break;}
if(bif.len>0)
for(j=bif.len;j>=k;j--)
j--; }
//有序表的插入
bif.BnoIdx[j+1]=bif.BnoIdx[j];
//记录后移
strcpy(bif.BnoIdx[k].bno,sh);
bif.len++;
//表长加 1
bif.BnoIdx[k].RecNo=i;
}
/*(3)修改书名索引以及书名链头索引表*/
void ChangeLinkHeadF1(BookDbaseFile &df,LHFile1 &lhf1)
{
char sm[20];
//图书主文件的当前长度,也就是要处理的当前记录号
//取记录中书名送至变量 sm 中
int i,j,k,m;
i=df.len;
strcpy(sm,df.BookDbase[i].bname);
j=1;k=0;
while(j<=lhf1.len1)
{
if(strcmp(sm,lhf1.LHFrec1[j].bname)==0)
{ k=j;break;} j++; }
if(k!=0)
{
df.BookDbase[i].namenext=lhf1.LHFrec1[k].lhead;
lhf1.LHFrec1[k].lhead=i;
lhf1.LHFrec1[k].RecNum++; }
//i 为主文件的当前记录号(假定为指针)
else {
m=++lhf1.len1;
//索引关键字个数加 1
df.BookDbase[i].namenext=0;
lhf1.LHFrec1[m].lhead=i;
lhf1.LHFrec1[m].RecNum=1;
strcpy(lhf1.LHFrec1[m].bname,sm);}}
//计数器置 1
//用头插法建立链表,指针置空
//i 为主文件的当前记录号(假定为指针)
/*(4)修改作者索引以及作者链头索引表*/
void ChangeLinkHeadF2(BookDbaseFile &df,LHFile2 &lhf2)
{
char zz[8];
//图书主文件的当前长度,也就是要处理的当前记录号
int i,j,k,m;
i=df.len;
strcpy(zz,df.BookDbase[i].author);//取记录中作者送至变量 zz 中
j=1;k=0;
while(j<=lhf2.len2)
{
if(strcmp(zz,lhf2.LHFrec2[j].author)==0)
{
break;
j++; }
k=j;
}
if(k!=0)
{
df.BookDbase[i].authnext=lhf2.LHFrec2[k].lhead;
lhf2.LHFrec2[k].lhead=i;
lhf2.LHFrec2[k].RecNum++; }
//i 为文件的当前记录号(假定为指针)
else{m=++lhf2.len2;
//索引关键字个数加 1
df.BookDbase[i].authnext=0;
lhf2.LHFrec2[m].lhead=i;
lhf2.LHFrec2[m].RecNum=1;
strcpy(lhf2.LHFrec2[m].author,zz);}}
//计数器置 1
//用头插法建立链表,指针置空
//i 为主文件的当前记录号(假定为指针)
/*(5)修改出版社索引以及出版社链头索引表。*/
void ChangeLinkHeadF3(BookDbaseFile &df,LHFile3 &lhf3)
{
char cbs[10];
//图书主文件的当前长度,也就是要处理的当前记录号
//取记录中书名送至变量 sm 中
int i,j,k,m;
i=df.len;
strcpy(cbs,df.BookDbase[i].press);
j=1;k=0;
while(j<=lhf3.len3)
{
if(strcmp(cbs,lhf3.LHFrec3[j].press)==0)
{
break;
j++; }
k=j;
}
if(k!=0)
{
df.BookDbase[i].prenext=lhf3.LHFrec3[k].lhead;
lhf3.LHFrec3[k].lhead=i;
lhf3.LHFrec3[k].RecNum++; }
//i 为主文件的当前记录号(假定为指针)
else {m=++lhf3.len3;
//索引关键字个数加 1
df.BookDbase[i].prenext=0;
lhf3.LHFrec3[m].lhead=i;
//用头插法建立链表,指针置空
//i 为主文件的当前记录号(假定为指针)
lhf3.LHFrec3[m].RecNum=1;
strcpy(lhf3.LHFrec3[m].press,cbs);}}
//计数器置 1
/*(6)建立图书多重表主索引及相关索引链头文件。*/
void CreateBook(BookDbaseFile &bf,BnoIdxFile &bif,LHFile1 &f1,LHFile2 &f2,LHFile3 &f3)
{
//输入记录
//修改书号索引文件
char yn='y';
while(yn=='y'||yn=='Y')
{
AppeDBaseRec(bf);
ChangeBnoIdxF(bf,bif);
ChangeLinkHeadF1(bf,f1);
ChangeLinkHeadF2(bf,f2);
ChangeLinkHeadF3(bf,f3);
cout<<"继续输入吗? y/n :";
cin>>yn;
} }
/*reader.c 读者管理子系统*/
void ReaderManage(ReadFile &rf)
{
i=++rf.len;
int i; char yn='y';
while(yn=='y'||yn=='Y')
{
printf("输入读者号 读者名 可借图书数\n");
scanf("%s %s",rf.ReadRec[i].rno,rf.ReadRec[i].name);
scanf("%d",&rf.ReadRec[i].bn1);
rf.ReadRec[i].bn2=0;
for(int j=1;j>yn;
i++;
readfile(BookDbaseFile &bf,BnoIdxFile &bif,LHFile1 &f1,LHFile2 &f2,LHFile3
/*readfile.c 读入盘中各类文件*/
void
&f3,ReadFile &rf,BbookFile &bbf)
{
int i; //读图书文件
exit(0); }
printf("Cannot open this file book.txt!\n");
FILE *fpout;
fpout=fopen("book","rb");
if(fpout==NULL)
{
while(!feof(fpout))
{fread(&bf.BookDbase[i],sizeof(BookRecType),1,fpout);
bf.len=i-1;
fclose(fpout);
fpout=fopen("bidx","rb");
if(fpout==NULL)
{
while(!feof(fpout))
{fread(&bif.BnoIdx[i],sizeof(BidxRecType),1,fpout); i++; if(feof(fpout))break;}
printf("Cannot open this file bidx.txt!\n");
//读书号索引文件
exit(0);} i=1;
i=1;
i++; if(feof(fpout))break;}
exit(0);}
i=1;
i++; }
exit(0);} i=1;
//读书名索引链头文件
fclose(fpout);
fclose(fpout);
//读出版社索引链头文件
bif.len=i-1;
fpout=fopen("nidx","rb");
if(fpout==NULL)
{ printf("Cannot open this file nidx.txt!\n");
while(!feof(fpout))
{fread(&f1.LHFrec1[i],sizeof(BNRecType),1,fpout);
//读作者索引文件
fpout=fopen("aidx","rb");
if(fpout==NULL)
{ printf("Cannot open this file aidx.txt!\n");
while(!feof(fpout))
{fread(&f2.LHFrec2[i],sizeof(BARecType),1,fpout);
f2.len2=i-1;
fpout=fopen("pidx","rb");
if(fpout==NULL)
{
while(!feof(fpout))
{fread(&f3.LHFrec3[i],sizeof(BPRecType),1,fpout);i++;
f3.len3=i-1;
fpout=fopen("read","rb");
if(fpout==NULL)
{
while(!feof(fpout))
{fread(&rf.ReadRec[i],sizeof(RRecType),1,fpout);i++;}
rf.len=i-1;
fpout=fopen("bbff","rb");
if(fpout==NULL)
{
while(!feof(fpout))
{fread(&bbf.Bbook[i],sizeof(BbookRecType),1,fpout);
bbf.len=i-1;
printf("Cannot open this file pidx.txt!\n");
printf("Cannot open this file read.txt!\n");
printf("Cannot open this file bbff.txt!\n");
fclose(fpout);
//读借还书文件
fclose(fpout);
//读读者文件
fclose(fpout);}
exit(0);}
exit(0);}
exit(0);}
i=1;
i++; }
f1.len1=i-1;
fclose(fpout);
}
i=1;
i=1;
i++; }
//search.c
/*(1)书号查询算法.用二分法查找实现书号查询算法如下*/
int BinSearch(BnoIdxFile bif,char key[])
{
low=1;
int low,high,mid;
while(low<=high){
high=bif.len;
mid=(low+high)/2;
if(strcmp(key,bif.BnoIdx[mid].bno)==0)return bif.BnoIdx[mid].RecNo;
else if(strcmp(key,bif.BnoIdx[mid].bno)<0) high=mid-1;
else low=mid+1;}
return 0;}//BinSearch
/*(2)按书名查询算法*/
int BnameFind(LHFile1 lhf1,char key[])
for(i=1;i<=lhf1.len1;i++)
{int i,k=0;
{if(strcmp(key,lhf1.LHFrec1[i].bname)==0)