基于C语言实现的图书管理系统

simpleLove

发布日期: 2018-10-06 21:47:48 浏览量: 798
评分:
star star star star star star star star star_border star_border
*转载请注明来自write-bug.com

一、设计目的

通过C语言实现图书管理的功能,而且能够实现账户的注册、登录、以及账户权限的区分,比如在管理员权限下的增加图书、查找图书、修改图书信息、删除单个图书信息、借书功能、快速还书、还有全部删除、一键保存的功能。这些基础的功能都是管理员管理时使用的实用功能。当然对于用户即同学来说,功能限制到只有查找、借书、还书三大功能!因为对于用户来说他的权限不足以支持他做出破坏数据的操作。

二、设计内容

  • 登录程序
    管理员登录:新增图书;查询图书;修改图书;删除图书;借出图书;归还图书;全部删除;一键保存;退出程序
    用户登录:查询图书;借出图书;归还图书;退出程序

  • 注册账号
    管理员注册
    用户注册

  • 退出程序

三、概要设计

功能模块图如下所示:

3.1 各个模块详细的功能描述。

登录功能

登录界面时一样,管理员与用户没有区别,但是登录成功时,系统将会根据权限生成不同的使用界面,以及功能限制。

管理员功能

管理员权限为高级,管理员可以对图书数据进行一系列的管理:

  • 新增图书时可以进行添加图书的各种信息
  • 查询图书时可以对书号、书名、作者、出版社、类别进行模糊搜索,届时所有符合条件的结果都会出现
  • 修改时只能对某一确定的书籍进行修改,以具体的书号或书名进行检索,可以在修改时跳过某项即不修改
  • 删除图书与修改时相同,只能对某一确定书籍进行删除操作
  • 借出图书时对某一确定书籍进行检索,如果借出会提示借出,并显示归还时间,否则将只需要输入归还时间,借出时间自动生成为当天时间
  • 归还时只需要将归还的图书书名输入即可归还图书
  • 全部删除时会进行最多三次的询问,询问是否继续删除,防止误删操作
  • 一键保存会将所有图书信息保存在固定的位置
  • 退出程序将会退出使用

用户功能

用户功能由于权限不同、其他功能不对用户开放,用户也不能按对应的键进行操作。

注册账号

注册账号时有两种注册方式、管理员注册、用户注册,但是其实在输入昵称,密码时候都是同样的,两次密码不一致会进行重新输入,且密码必须大于6位小于等于16位。当注册时会提示是否为管理员,如果是管理员则会要求输入管理员内码,否则直接跳过提示是否注册,这时系统会自动生成一个账号,然后返回登录注册界面。

四、详细设计

4.1 功能函数的调用关系图

4.2 各功能函数的数据流程图

  1. struct book *read() //读取文件中信息到链表

  1. struct book *creat(int j,int k,int type,struct book *goost)//插入数据到链表,新增图书

  1. void visitall()//查询某一本书的信息

  1. int compare(char str[],struct book *key)//返回1表示条件符合模糊,0不符合

  1. void deletebook(int type)//删除图书//type表示删除类型//1为单个删除//2为全部删除

4.3 重点设计及编码

  1. //返回1表示条件符合模糊,0不符合
  2. int compare(char str[],struct book *key)
  3. {
  4. int size,sizenumber,sizename,sizekind,sizeadress,sizeauthor,i,j,success[5]= {0,0,0,0,0};
  5. size=strlen(str);//获取关键信息的长度
  6. sizenumber=strlen(key->number);//获取书号的长度
  7. sizename=strlen(key->name);//获取书名的长度
  8. sizekind=strlen(key->kind);//获取类别的长度
  9. sizeadress=strlen(key->adress);//获取出版社的长度
  10. sizeauthor=strlen(key->author);//获取作者的长度
  11. for(i=0;i<sizenumber-size+1;i++)//对书号进行模糊判定
  12. {
  13. success[0]=1;
  14. for(j=0;j<size;j++)
  15. {
  16. if(str[j]!=key->number[j+i])
  17. {
  18. success[0]=0;
  19. }
  20. }
  21. if(success[0]==1)
  22. {
  23. break;
  24. }
  25. }
  26. for(i=0;i<sizename-size+1;i++)//对书名进行模糊判定
  27. {
  28. success[1]=1;
  29. for(j=0;j<size;j++)
  30. {
  31. if(str[j]!=key->name[j+i])
  32. {
  33. success[1]=0;
  34. }
  35. }
  36. if(success[1]==1)
  37. {
  38. break;
  39. }
  40. }
  41. for(i=0;i<sizekind-size+1;i++)//对书类进行模糊判定
  42. {
  43. success[2]=1;
  44. for(j=0;j<size;j++)
  45. {
  46. if(str[j]!=key->kind[j+i])
  47. {
  48. success[2]=0;
  49. }
  50. }
  51. if(success[2]==1)
  52. {
  53. break;
  54. }
  55. }
  56. for(i=0;i<sizeadress-size+1;i++)//对出版社进行模糊判定
  57. {
  58. success[3]=1;
  59. for(j=0;j<size;j++)
  60. {
  61. if(str[j]!=key->adress[j+i])
  62. {
  63. success[3]=0;
  64. }
  65. }
  66. if(success[3]==1)
  67. {
  68. break;
  69. }
  70. }
  71. for(i=0;i<sizeauthor-size+1;i++)//对作者进行模糊判定
  72. {
  73. success[4]=1;
  74. for(j=0;j<size;j++)
  75. {
  76. if(str[j]!=key->author[j+i])
  77. {
  78. success[4]=0;
  79. }
  80. }
  81. if(success[4]==1)
  82. {
  83. break;
  84. }
  85. }
  86. if((success[0]+success[1]+success[2]+success[3]+success[4])!=0)//如果有一项满足情况,则返回1,否则即所有项都不符合,则返回0
  87. {
  88. return 1;
  89. }
  90. else
  91. {
  92. return 0;
  93. }
  94. }
  1. //在合适合法输入字符串//i,j表示光标的定位//type表示要求达到的目的
  2. void cuowu(int i, int j,int type,char str[])
  3. {
  4. char str1[40];//定义中间传递字符串
  5. fflush(stdin);
  6. if(type==0)//类型0表示字符串内没有值,输入回车光标返回继续执行输入
  7. {
  8. gotoxy(i,j);
  9. gets(str1);
  10. while (str1[0] == 13 || str1[0] == 10 || str1[0] == 0)
  11. {
  12. gotoxy(i, j);
  13. gets(str1);
  14. fflush(stdin);
  15. }
  16. sprintf(str,"%s",str1);//将合法字符串打印到目标字符串
  17. }
  18. else//类型为1表示目标字符串有值,回车后跳过输入,进入下一个
  19. {
  20. gotoxy(i,j);
  21. gets(str1);
  22. if(str1[0]!=13&&str1[0]!=10&&str1[0]!=0)
  23. {
  24. sprintf(str,"%s",str1);
  25. }
  26. }
  27. fflush(stdin);
  28. }
  1. //头插法//i,j定位光标//type为类型//1为输入//2为修改//3为借出,通过输入type使三个功能合而为一,公用代码!
  2. struct book *creat(int j,int k,int type,struct book *goost)
  3. {
  4. struct book *pnew;
  5. time_t timep;
  6. struct tm *p;
  7. int howtype=0;//区别的输入类型变量
  8. if(type==1||type==2)
  9. {
  10. if(type==1)//1时进行输入操作,创建新的链表节点,并提示输入
  11. {
  12. pnew=(struct book*)malloc(sizeof(struct book));
  13. book_num++;
  14. if(book_num==1)
  15. {
  16. phead=pnew;
  17. phead->next=NULL;
  18. phead->last=NULL;
  19. }
  20. else if(book_num==2)
  21. {
  22. phead->next=pnew;
  23. pnew->last=phead;
  24. pnew->next=NULL;
  25. }
  26. else
  27. {
  28. pnew->next=phead->next;
  29. phead->next->last=pnew;
  30. pnew->last=phead;
  31. phead->next=pnew;
  32. }
  33. gotoxy(k,j++);
  34. printf("书号:");
  35. gotoxy(k,j++);
  36. printf("书名:");
  37. gotoxy(k,j++);
  38. printf("作者:");
  39. gotoxy(k,j++);
  40. printf("类别:");
  41. gotoxy(k,j++);
  42. printf("出版社:");
  43. gotoxy(k,j++);
  44. printf("价格:");
  45. gotoxy(k,j++);
  46. printf("是否借出?(在库为是;借出为否):");
  47. }
  48. else
  49. {
  50. howtype=1;//通过howtype进行控制输入的方式,即修改时与新增数据的不同
  51. }
  52. cuowu(k+6,j-7,howtype,pnew->number);
  53. cuowu(k+6,j-6,howtype,pnew->name);
  54. cuowu(k+6,j-5,howtype,pnew->author);
  55. cuowu(k+6,j-4,howtype, pnew->kind);
  56. cuowu(k+8,j-3,howtype, pnew->adress);
  57. cuowu(k+6,j-2,howtype, pnew->price);
  58. cuowu(k+34,j-1,howtype, pnew->type);
  59. while(strcmp(pnew->type,strno)!=0&&strcmp(pnew->type,strok)==0)//非法字符串返回重新输入
  60. {
  61. cuowu(k+34,j-1,howtype, pnew->type);
  62. }
  63. }
  64. if(strcmp(pnew->type,strno)==0)
  65. {
  66. if(type==3)//借出图书直接显示借出时间,并提示输入归还时间
  67. {
  68. time(&timep);
  69. p=localtime(&timep);
  70. sprintf(pnew->lendtime,"%4d.%2d.%2d",(1900+p->tm_year), (1+p->tm_mon),p->tm_mday);//获取当天日期,作为借书日期
  71. gotoxy(k, j-2);
  72. printf("借出时间(例:2015.06.02):%s",pnew->lendtime);
  73. gotoxy(k, j-1);
  74. printf("归还时间(例:2015.06.02):");
  75. cuowu(k+25,j-1,1, pnew->backtime);
  76. }
  77. else//否则进行正常的输入
  78. {
  79. gotoxy(k, j++);
  80. printf("借出时间(例:2015.06.02):");
  81. gotoxy(k, j++);
  82. printf("归还时间(例:2015.06.02):");
  83. cuowu(k+25,j-2,howtype, pnew->lendtime);
  84. cuowu(k+25,j-1,howtype, pnew->backtime);
  85. }
  86. }
  87. else
  88. {
  89. sprintf(pnew->lendtime,"0000.00.00");
  90. sprintf(pnew->backtime,"0000.00.00");
  91. }
  92. allsort();//进行排序
  93. return phead;
  94. }

五、测试数据及运行结果

5.1 正常测试数据和运行结果

要求提供3组正常测试数据和运行结果

开始界面 管理员注册 用户注册

登录界面

管理员界面和用户界面

管理员界面 用户界面

三组图书输入数据

输入数据1 输入数据2 输入数据3

修改图书和修改后查询

修改图书 修改后查询

借出已被借图书和借出在库图书

借出已被借图书 借出在库图书

归还图书

删除图书和删除后查询

删除图书 删除后查询

一键保存和全部删除

一键保存 全部删除

5.2 异常测试数据及运行结果

多次错误登陆,显示拜拜

新增图书时按回车视为非法,不进行换行

输入非法字符串时不执行下一步,返回

查询时查询没有的书目

借出时借出没有的书目

进行下一步判断执行时输入非法操作,返回继续输入

六、调试情况,设计技巧及体会

6.1 改进方案

对自己的设计进行评价,指出合理和不足之处,提出改进方案;

  • 合理之处:在规避非法输入的时候考虑到了有可能会有人不小心点到回车键执行了换行操作,导致数据输入发生错误是别的问题,为此特意写了void cuowu(int i, int j,charstr[]);函数,并且在新增图书、修改图书、借出图书时将众多的功能实现在一个struct book *creat(int j, int k, int type, struct book *goost)函数里,当然在搜索时使用模糊搜索使得搜索更加方便。

  • 不足之处:在规避非法输入的时候没有考虑到字符串长度的问题,如果违规输入过长的字符串将会导致整个系统的崩溃,应该改进void cuowu(int i, int j, char str[]);函数,再加上一个参数把字符串的长度限制加上,使字符串不会出现越界问题。

6.2 体会

对设计及调试过程的心得体会。

在这次课设最初开始的时候我想做的是一个通讯录管理系统,因为当时我的通讯录已经写了670行程序也就是四分之三的样子,但是在开始之后我发现通讯录写起来的意义不怎么大,于是我选择了图书管理系统下手,最开始的两天课设我的定位是做出最基本的功能先,因为其他的功能都是可以作为后期添加加上的。在最初的三天我只是把所有的功能写完,但是我一次都没有进行调试,我觉得我的逻辑是对的,一起调试也是可以的,于是后面两天基本上都是在调试中度过,因为我做的是文本界面,有需要光标随意的移动,所以写起来需要有一个大局观,因为整个屏幕的光标移动都是需要考虑的,整个程序只要涉及到标准的输入输出时都是需要跟踪光标位置的,所以在调试的时候大多数时间都是在调试跟踪光标。

经过这次课设,我对各种C函数的理解更加深入,课设过程中让我懂得了许许多多。作为一个程序来说,程序员首先要做得就是定义它的基本框架,否则注定是写出一堆乱码,有一个大致的目标才好去实现!在写程序的时候也要考虑的更加全面一些,让程序的容错性更强,因为对于使用者来说,总有各种各样的操作是不可避免的,所以我们能做的就是考虑各种极限情况,把可能发生的事情全部都考虑到位!

上传的附件 cloud_download 图书管理系统-课程设计.7z ( 492.67kb, 4次下载 )
error_outline 下载需要13点积分

发送私信

成功一定有方法,失败一定有原因

6
文章数
8
评论数
最近文章
eject