图书管理系统

250 篇文章 1 订阅
250 篇文章 0 订阅
源码下载  http://www.byamd.xyz/hui-zong-1/

一. 设计目的

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

二. 设计内容

  • 登录程序
  1. 管理员登录

    1.新增图书2.查询图书3.修改图书4.删除图书5.借出图书6.归还图书7.全部删除8.一键保存9.退出程序

  2. 用户登录

    1.查询图书2.借出图书3.归还图书4.退出程序

  • 注册账号
  1. 管理员注册

  2. 用户注册

  • 退出程序

三.概要设计

1.功能模块图;

图书管理系统

登录程序

注册账号

退出程序

管理员登录

用户登录

新增书籍

查询图书

修改图书

删除图书

借出图书

归还图书

全部删除

一键保存

退出程序

查询图书

借出图书

归还图书

退出程序

管理员注册

用户注册

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

登录程序

管理员登录

用户登录

管理员登录

新增图书

查询图书

修改图书

删除图书

借出图书

归还图书

全部删除

一键保存

退出程序

(2)管理员功能

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

  1. 新增图书时可以进行添加图书的各种信息。

  2. 查询图书时可以对书号、书名、作者、出版社、类别进行模糊搜索,届时所有符合条件的结果都会出现。

  3. 修改时只能对某一确定的书籍进行修改,以具体的书号或书名进行检索,可以在修改时跳过某项即不修改。

  4. 删除图书与修改时相同,只能对某一确定书籍进行删除操作。

  5. 借出图书时对某一确定书籍进行检索,如果借出会提示借出,并显示归还时间,否则将只需要输入归还时间,借出时间自动生成为当天时间。

  6. 归还时只需要将归还的图书书名输入即可归还图书。

  7. 用户登录

查询图书

借出图书

归还图书

退出程序

  1. 一键保存会将所有图书信息保存在固定的位置

  2. 退出程序将会退出使用

(3)用户功能

注册账号

管理员注册

用户注册

(4)注册账号

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

四.详细设计

1.功能函数的调用关系图

(Source Insight生成)

2.各功能函数的数据流程图

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

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

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

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

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

3.重点设计及编码

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

{

int
size,sizenumber,sizename,sizekind,sizeadress,sizeauthor,i,j,success[5]={0,0,0,0,0};

size=strlen(str);//获取关键信息的长度

sizenumber=strlen(key->number);//获取书号的长度

sizename=strlen(key->name);//获取书名的长度

sizekind=strlen(key->kind);//获取类别的长度

sizeadress=strlen(key->adress);//获取出版社的长度

sizeauthor=strlen(key->author);//获取作者的长度

for(i=0;i<sizenumber-size+1;i++)//对书号进行模糊判定

{

success[0]=1;

for(j=0;j<size;j++)

{

if(str[j]!=key->number[j+i])

{

success[0]=0;

}

}

if(success[0]==1)

{

break;

}

}

for(i=0;i<sizename-size+1;i++)//对书名进行模糊判定

{

success[1]=1;

for(j=0;j<size;j++)

{

if(str[j]!=key->name[j+i])

{

success[1]=0;

}

}

if(success[1]==1)

{

break;

}

}

for(i=0;i<sizekind-size+1;i++)//对书类进行模糊判定

{

success[2]=1;

for(j=0;j<size;j++)

{

if(str[j]!=key->kind[j+i])

{

success[2]=0;

}

}

if(success[2]==1)

{

break;

}

}

for(i=0;i<sizeadress-size+1;i++)//对出版社进行模糊判定

{

success[3]=1;

for(j=0;j<size;j++)

{

if(str[j]!=key->adress[j+i])

{

success[3]=0;

}

}

if(success[3]==1)

{

break;

}

}

for(i=0;i<sizeauthor-size+1;i++)//对作者进行模糊判定

{

success[4]=1;

for(j=0;j<size;j++)

{

if(str[j]!=key->author[j+i])

{

success[4]=0;

}

}

if(success[4]==1)

{

break;

}

}

if((success[0]+success[1]+success[2]+success[3]+success[4])!=0)//如果有一项满足情况,则返回1,否则即所有项都不符合,则返回0

{

return 1;

}

else

{

return 0;

}

}

(2)void cuowu(int i, int j,int type,char
str[])//在合适合法输入字符串//i,j表示光标的定位//type表示要求达到的目的

{

char str1[40];//定义中间传递字符串

fflush(stdin);

if(type==0)//类型0表示字符串内没有值,输入回车光标返回继续执行输入

{

gotoxy(i,j);

gets(str1);

while (str1[0] == 13 || str1[0] == 10 || str1[0] == 0)

{

gotoxy(i, j);

gets(str1);

fflush(stdin);

}

sprintf(str,"%s",str1);//将合法字符串打印到目标字符串

}

else//类型为1表示目标字符串有值,回车后跳过输入,进入下一个

{

gotoxy(i,j);

gets(str1);

if(str1[0]!=13&&str1[0]!=10&&str1[0]!=0)

{

sprintf(str,"%s",str1);

}

}

fflush(stdin);

}

(3)struct book *creat(int j,int k,int type,struct book
*goost)//头插法//i,j定位光标//type为类型//1为输入//2为修改//3为借出,通过输入type使三个功能合而为一,公用代码!

{

struct book *pnew;

time_t timep;

struct tm *p;

int howtype=0;//区别的输入类型变量

if(type1||type2)

{

if(type==1)//1时进行输入操作,创建新的链表节点,并提示输入

{

pnew=(struct book*)malloc(sizeof(struct book));

book_num++;

if(book_num==1)

{

phead=pnew;

phead->next=NULL;

phead->last=NULL;

}

else if(book_num==2)

{

phead->next=pnew;

pnew->last=phead;

pnew->next=NULL;

}

else

{

pnew->next=phead->next;

phead->next->last=pnew;

pnew->last=phead;

phead->next=pnew;

}

gotoxy(k,j++);

printf(“书号:”);

gotoxy(k,j++);

printf(“书名:”);

gotoxy(k,j++);

printf(“作者:”);

gotoxy(k,j++);

printf(“类别:”);

gotoxy(k,j++);

printf(“出版社:”);

gotoxy(k,j++);

printf(“价格:”);

gotoxy(k,j++);

printf(“是否借出?(在库为是;借出为否):”);

}

else

{

howtype=1;//通过howtype进行控制输入的方式,即修改时与新增数据的不同

}

cuowu(k+6,j-7,howtype,pnew->number);

cuowu(k+6,j-6,howtype,pnew->name);

cuowu(k+6,j-5,howtype,pnew->author);

cuowu(k+6,j-4,howtype, pnew->kind);

cuowu(k+8,j-3,howtype, pnew->adress);

cuowu(k+6,j-2,howtype, pnew->price);

cuowu(k+34,j-1,howtype, pnew->type);

while(strcmp(pnew->type,strno)!=0&&strcmp(pnew->type,strok)==0)//非法字符串返回重新输入

{

cuowu(k+34,j-1,howtype, pnew->type);

}

}

if(strcmp(pnew->type,strno)==0)

{

if(type==3)//借出图书直接显示借出时间,并提示输入归还时间

{

time(&timep);

p=localtime(&timep);

sprintf(pnew->lendtime,"%4d.%2d.%2d",(1900+p->tm_year),
(1+p->tm_mon),p->tm_mday);//获取当天日期,作为借书日期

gotoxy(k, j-2);

printf(“借出时间(例:2015.06.02):%s”,pnew->lendtime);

gotoxy(k, j-1);

printf(“归还时间(例:2015.06.02):”);

cuowu(k+25,j-1,1, pnew->backtime);

}

else//否则进行正常的输入

{

gotoxy(k, j++);

printf(“借出时间(例:2015.06.02):”);

gotoxy(k, j++);

printf(“归还时间(例:2015.06.02):”);

cuowu(k+25,j-2,howtype, pnew->lendtime);

cuowu(k+25,j-1,howtype, pnew->backtime);

}

}

else

{

sprintf(pnew->lendtime,“0000.00.00”);

sprintf(pnew->backtime,“0000.00.00”);

}

allsort();//进行排序

return phead;

}

五.测试数据及运行结果

1.正常测试数据和运行结果

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

(左)开始界面(中)管理员注册(右)用户注册

登录界面

(左)管理员登录(右)用户界面

三组图书输入数据

(一)修改图书中(二)修改后查询

(一)借出已被借图书(二)借出在库图书

归还图书

(左)删除图书(右)删除后查询

(左)一键保存(右)全部删除

2.异常测试数据及运行结果

要求提供2组异常测试数据和运行结果

多次错误登陆,显示拜拜

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

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

查询时查询没有的书目

借出时借出没有的书目

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

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

1.改进方案

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

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

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

2.体会

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

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

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

七.参考文献

c语言程序设计教程 王曙燕

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值