当前位置:首页 > C语言课程设计(图书销售管理系统)
图书销售管理系统
老师的程序,用三个指针,很顺利的就解决了。如果文件打开失败的话,释放结点就会出错。比如我的程序(导入书库信息) 中的p3->next=NULL,因为文件打开失败,这样就不会进入动态申请存储空间,这样p3->next=NULL就会没有意义。解决办法:进入导入书库函数(void loadrec)时,执行p3=head.即使p3有所指向,就可以解决。
(4)查询函数void search()。通过书号查询时实现比较容易,找不到时就直接显示找不到,找到就输出,因为一个书号只会对应一本书,循环好做。而通过书名和作者查询时,可以有多本同名的书或有多本同作者的书。这时,就需要先做一个循环,看操作者要查询的书名或作者是否存在,若在,就再弄一个循环,从刚才找到的结点后面再开始查找,将与刚才找到的结点相同的信息的结点再输出,直到结点全部检查完。
(5)图书销售函数void buy(),为了购买(任何操作者对管理系统来说都是图书购买者)图书操作简便,我将程序限定在只能通过书号来购买图书,因为一个书号只会对应一本书。但这样就会产生一个问题,如果购买者不知道书号,但知道书名或作者,那他就购买不成图书了。解决办法:程序首先默认购买者知道书号,当没有找到购买者所找的书号时,程序就会提示,是否要调用查询功能,当执行调用时,购买者就可以根据自己知道的图书信息(书名或作者),选择相应的查询渠道,这样购买者就可以查看自己要找的书在不在,若在,就可以看着列表信息,重新输入书号进行购买,这样就间接支持了多渠道购买。为了满足多次购买,我用了一个循环,当购买者想结束购买时,执行相应按键,才可结束购买。当在最后结束购买时,程序也会提示购买者是否确认购买,此时亦可确认,也可撤销,这样就比较符合实际要就和人性化。
(6)图书信息整体浏览函数void list(),实现起来较简单,直接输出结点,直至结束。
(7)图书信息删除函数void delet(),进入图书删除需要密码,没有密码者不能进行删除操作,为了防止有人恶意试密码,程序限制了密码输入次数,超过了3次,程序就会返回到主菜单。程序要求支持通过书号、书名、作者,三种删除方式,没卖完的书不能删除。通过书号删除时实现起来比较简单,而通过书名和作者删除就很麻烦,因为同一个书名或作者的书可以有多本,而这多本里面可能一部份已尽卖完,有些又没卖完,要删除的结点还可能不止一个。为了解决这个问题,在通过书号删除时,我通过while()循环,找到要删除的图书书号,找到该结点直接删除,但是通过书名和作者删除时,这种方式就行不通了,由于再删除过程中需要判断要删除的结点的位置,这样就不能同时删除已售完的多本同书名或作者的书。于是再通过书名和作者删除时,我先创建一个链表,将满足删除要求的图书储存在一起,然后将做一个循环判断,将书库中与该链表储存的相同的图书(信息)一个个删除(删除方式同通过书号删除),直至该链表中的结点走完。这种方式实现起来简单,但比较耗费程序运行的速度,解决思路不容易想到。再删除过程中,为了便于删除,防止操作者不知道有哪些书已经卖完,程序可以调用函数void bover(),显示已经售完的书,看着列表信息进行删除。 (8)保存记录函数void save(),实现比较简单。
(9)退出void exit0(),退出时,为了防止操作者忘记保存记录,在退出程序时,程序会提醒操作者是否需要保存,这时操作者可以以选择保存或不保存,这样在操作者操作失误时,在退出时,也避免了强制保存。
(10)新建书库信息函数和修改密码函数,题目并未作要求,在此就不再介绍。
第 24 页 共 58 页
图书销售管理系统
(2) 集成调试过程及结果。
1在各模块协调操作时,几乎各个功能模块都需要得到头指针(head)○,为此我将保
存导入书库信息的链表中需要用到的指针定义成全局的,这样便于操作,可防止头指针传错。
2为了使在退出和记录保存函数中,在不同的情况下给出不同的提示信息,我定义○
了一个标志性全局变量int save_flag=0;/*信息变动标志*/。在可使书库信息变动的函数中,当书库信息变动成功时,就执行save_flag=1,这样在退出或保存过程中就知道书库信息是否变动过,以便实现相应功能。
3在购书过程中,为了间接支持多渠道购书,可以调用查询函数void search(),○
在主菜单中也可执行查询功能,但是在这两种调用过程中,要求却不是一样的,在购书函数中调用时,查询功能是分次调用的,不能连续执行查询,而且显示的查询信息是不能清屏的,因为操作者需要看着查询得到的列表信息输入书号。在主函数中执行此项功能时,是要支持连续查询的,而且需要清屏上次执行查询时显示的信息。为了实现这个要求我定义了一个全局变量int buy_flag=0,在菜单中执行查询时,首先执行buy_flag=0,在购买图书函数中调用查询功能时,首先执行buy_flag=1.然后通过判断buy_flag的值,在查询功能中实现相应功能。
4在删除图书时,在要删除的图书信息没找到时,程序会提醒操作者,是否要显示○
已售完的图书void bover(),在调用void bover()后,操作者可以看着列表图书信息进行删除,此时程序就不能再可以返回到删除方式菜单,为此我定义了一个全局变量int shan_flag=0,当调用了void bover()后执行shan_flag=1,当删除操作成功后,执行shan_flag=0,这样在显示删除菜单时根据shan_flag的值,就可以完成相应的功能。结合这些全局变量会使界面变得更流畅和美观。
5密码我将其定义成全局变量,这样当我修改密码(题目未作要求,是我自己加的)○
时,进行删除操作的密码就会跟着改变。 6导入书库信息时,○程序读文件时会将下一行的回车符读进来,这样就会出现乱码。如果我删掉文件中的最后一个回车符,导入和整体浏览图书信息会正常,但是当我执行新建图书信息(题目为做要就,是我自己加的)或者图信息变动过后,保存信息时,文件自身又会在数据最后加上一个回车符,后来我上网搜到资料,弄懂了是咋回事。
我们一般读取文件方式:
head =p3=p1=(struct book*)malloc(LEN);/*开辟一个新单元*/ p1->next=NULL; while(!feof(fp)) {
n++;
fscanf(fp,\benshu);
p2=(struct book*)malloc(LEN);/*继续开辟一个新单元,直到文件读完*/ p1->next=p2; p3=p1;
第 25 页 共 58 页
图书销售管理系统
p1=p2;
p1->next=NULL; }
free(p2);p3->next=NULL;/*释放多申请的一个单元*/
这样,当fscanf读到最后一个回车符时,发现文件结束,但这时,信息已经读入。 真确读取:
head=p3=p1=(struct book*)malloc(LEN);/*开辟一个新单元*/ p1->next=NULL;
p7=(struct book*)malloc(LEN);
fscanf(fp,\benshu);
while(!feof(fp)) {
n++;
*p1=*p7;
p2=(struct book*)malloc(LEN);/*继续开辟一个新单元,直到文件读完*/ p1->next=p2; p3=p1; p1=p2;
p1->next=NULL;
fscanf(fp,\benshu); }
free(p2);p3->next=NULL;/*释放多申请的一个单元*/
利用中间的一个变量p7做一个临时存储空间,文件没结束,再将其信息给p1。
(3) 功能调试过程及结果。
1首先根据题目,新建一个文件,执行程序,看程序是否能够正常读取文件。读取○
正常。
2分别执行不同的函数看,是否能正常运行。各个程序单独执行正常。 ○
3在运行一次的情况下,连续执行不同函数,检查是否有逻辑错误。 ○
4在执行了相应的函数后,对比文件,看文件是否按程序操作的结果,正确改变了。○ 5将文件删除,看程序是否会给出正确提示,并且限制某些没有文件不能实现的功○能。
6将文件置空,看是否会给出相应提示以及程序是否运行正常。 ○
第 26 页 共 58 页
图书销售管理系统
6.2程序测试
各模块测试用例数据及结果
显示结果一致(图书整体浏览函数)
第 27 页 共 58 页
共分享92篇相关文档