C语言课程设计图书销售管理系统.docx
- 文档编号:30748629
- 上传时间:2023-08-20
- 格式:DOCX
- 页数:83
- 大小:667.53KB
C语言课程设计图书销售管理系统.docx
《C语言课程设计图书销售管理系统.docx》由会员分享,可在线阅读,更多相关《C语言课程设计图书销售管理系统.docx(83页珍藏版)》请在冰豆网上搜索。
C语言课程设计图书销售管理系统
HUBEIUNIVERSITYOFAUTOMOTIVETECHNOLOGY
C语言程序设计
课程设计报告
课设题目:
图书销售管理系统
专业:
电气工程及其自动化
班级:
KT1223-1
姓名:
********
成绩:
完成日期:
2012年12月28日-2013年1月11日
指导教师:
************
目录目录
5.6图书信息保存界面:
22
5.9修改密码23
1.课程设计目的
1)通过课程设计,加深对结构化程序设计思想的理解,能对系统功能进行分析,并设计合理的模块化结构。
2)通过课程设计,进一步掌握C语言中重要的数据结构。
掌握并熟练运用指针、链表、结构体、文件等数据结构。
3)通过课程设计,提高程序开发能力,能运用合理的控制流编写清晰高效的程序。
4)通过课程设计,培养C语言知识运用和自学能力,真正的把课堂上获得的知识运用起来,培养自己对程序编写的兴趣,并能独立设计和实现一个小型系统。
5)通过课程设计,加强了自己的程序分析能力。
2.需求分析
2.1要求
1)遵循软件开发过程的基本规范;能灵活应用,初步具备运用C程序解决实际问题的能力。
2)运用结构化程序设计方法,按照课程设计题目要求,完成包括需求分析、数据结构设计、概要设计、详细设计、编写代码、调试和测试C程序等过程。
3)学会利用数组、结构体、链表进行相关信息表示。
4)功能模块划分清晰,系统结构图符合功能操作要求,且有详尽的功能描述
5)各主要功能模块有详尽的流程图及描述,用函数的形式实现,且调用入口、功能、出口等关系正确。
6)所设计的C程序较好的可读性和可靠性;程序书写风格规范,注释清晰。
7)界面友好(良好的人机互交),凡需要输入信息时,都有较详尽的提示信息,并对输入信息有较完善的值域分析。
8)程序经上机调试通过,不应出现语法型、功能型错误,并获得满意的结果。
9)学会通过各功能性测试用例测试程序的能力,尽可能避免原则性错误的出现。
10)掌握编写、调试和测试C语言程序的基本技巧,充分理解结构化程序设计的基本方法。
11)C语言课程设计报告的内容反应实际设计过程,且符合格式要求,无抄袭现象。
2.2任务描述
此系统以图书销售为背景,支持书店管理人员对图书信息进行新建、查询、整体列表浏览、删除(需要密码),同时也支持图书购买者进行图书信息的查询。
图书信息从文件中载入,当图书信息变动过时,亦可实现保存。
具体功能实现如下:
1)图书信息载入:
系统自动从文件中读入书库信息,以便操作者可以实现相关需求。
2)新建功能:
当书库进了不同的新书回来时,可通过此功能将新书加入书库。
3)图书信息整体浏览功能:
实现对书库信息的整体浏览,使书库管理人员对书库信息有一个整体的了解。
4)图书信息查询功能:
实现对图书按书号、书名或作者名进行查询。
5)图书信息删除功能:
实现对已卖完的图书进行清理。
6)修改密码功能:
书店管理人员可以拥有密码,进行图书删除。
通过修改密码,确保书库信息安全
2.3运行环境
1)WindowsXP/7系统
2)VC++6.0编译环境
2.4开发工具
C语言
3.总体设计
3.1系统流设计
本系统的功能模块如图1所示,主要有以下模块:
图1系统功能模块图
3.2系统模块设计
1)课程名称界面:
构造函数voidauther(),实现软件名称以及作者的显示。
2)系统欢迎界面:
构造函数voidwelcome(),实现欢迎使用图书销售管理系统的显示。
3)主菜单界面:
构造函数intmenu(),实现系统主菜单的显示。
4)图书信息自动导入:
构造函数voidloadrec(),实现系统自动导入图书信息。
5)图书信息新建:
构造函数voidcreate(),实现新建图书信息。
6)图书信息查询:
构造函数voidsearch(),实现查询界面的显示。
并通过对按按书号查询函数search_by_bnum、按书名查找函数search_by_bname、按作者查找函数search_by_author的调用,实现对图书信息的查询。
7)图书信息整体浏览:
构造函数voidlist(),显示当前书库所有书的信息。
8)图书销售:
构造函数voidbuy(),实现通过书号购书,并可调用查询功能,实现从其他途径找到书号。
9)图书信息删除:
构造函数voiddelet(),实现对已售完的图书进行清理,并通过对按书号删除函数delet_by_bnum、按书名删除函数delet_by_bname、按作者删除函数delet_by_author的调用,实现对图书信息的删除。
10)图书信息保存:
构造函数voidsave(),实现对图书信息变动后的保存。
11)修改密码:
构造函数voidredef(),实现修改密码。
12)退出系统:
构造函数voidexit0(),实现退出系统。
4.详细设计
4.1数据结构设计
根据系统要求,系统中需要保存的数据信息,其结构如下:
数据项名称
数据项系统表示
数据类型
数据长度
备注
书号
bnum
char
21
书名
bname
Char
41
作者
author
Char
11
售价
bpay
Float
4
书存在状态
benshu
Int
4
为了充分利用内存空间和实现不受限制的新建、载入图书信息,采用链表的结构保存图书信息,在新建或导入一本图书信息时,创建一个图书信息的节点,将其插入到链表中,示意图如下。
为此,需声明一个类型为structbook的结构体,其成员为图书的基本信息。
然后通过对指针、链表、文件等数据结构的操作,实现对图书信息信息的载入、新建、查询、整体浏览、删除、保存,销售图书入,等一系列操作。
其中,结构体定义如下:
structbook
{
charbnum[21];
charbname[41];
charauthor[11];
floatbpay;
intbenshu;
structbook*next;
};
4.2模块接口设计
1)所有函数模块声明如下:
voidauther();/*显示课程名称*/
voidwelcome();/*显示欢迎界面*/
voidmenu();/*主菜单函数,显示主菜单,并返回用户的选择*/
voidloadrec();/*自动导入书库信息*/
voidcreate();/*新建图书信息*/
voidlist();/*图书信息整体浏览*/
voidbpay();/*销售图书*/
voiddelet();/*删除已售完的图书信息*/
voiddelet_by_bnum();/*通过书号删除*/
voiddelet_by_bname();/*通过书名删除*/
voiddelet_by_author();/*通过作者删除*/
voidsearch();/*查询书存在状态*/
voidsearch_by_bnum();/*通过书号查询*/
voidsearch_by_bname();/*通过书名查询*/
voidsearch_by_author();/*通过作者查询*/
voidsave();/*保存记录*/
voidredef();/*修改密码*/
voidexit0();/*退出*/
2)并定义14个全局变量:
intsave_flag=0;/*图书信息是否保存标志*/
structbook*head=NULL,*p1,*p2,*p3;/*用于新建和导入图书信息*/
*head2=NULL,*p4,*p5,*p6;/*用于销售图书*/
intbuy_flag=0;/*买书时,是否调用过查询功能标志*/
intshan_flag=0;/*删书时,是否调用过显示已售完书功能标志*/
intT=0;/*记录导入的书本数*/
charmima[11]="123456";/*初始密码*/
3)主要模块的实现
系统以主函数intmain()为入口,首先通过调用voidauthor()显示软件名称及技术开发者、调用voidwelcome()显示欢迎界面,再调用loadrec()函数导入书库信息,然后通过switch(menu()),显示主菜单,并利用intmenu()接受用户的返回值返回个主函数,再调用相关的函数进入到下一级菜单进行相关操作。
4.3以下是几个主要模块的流程图:
1)主函数:
N
Y
YN
图2主函数流程图
2)导入书库信息函数
YN
N
Y
图3信息浏览流程图
图3导入书库信息函数流程图
3)
删除图书信息函数:
Y
Y
NN
N
Y
Y
N
Y
Y
N
Y
N
图4删除图书信息函数流程图
4)销售图书:
N
Y
Y
N
N
Y
N
Y
N
Y
图5销售(购买)图书函数流程图
5.运行结果
5.1主菜单界面:
图6主菜单界面
输入功能选择,系统自动进入相应功能界面。
5.2图信息查找界面:
图7图书信息查找界面
输入选择进入相应查询方式
图8进入书号查询界面
也可选其他选项进入相应查询界面
图9通过书号查询
输入书号错误,按回车又返回查询菜单
图10通过书号查找结果显示
一本书只有一个书号
图11通过书名查找结果显示
同种书名的书可以有多本
5.3图书销售界面:
图12图书销售界面
默认操作者知道书号
图13书号输入有误
不知道书号可以选择Y调用查询功能通过其他方式找到所要购买的书的书
图14通过书名查找后界面
调用查询后可以查到你要购买的书的书号
图15通过调用查询购买了图书界面
此时可按N结束购书,按任意键继续购书
图16不调用查询
图17购买图书界面
通过书作者找到了想要的图书
图18图书购买后,已购图书显示界面
图19确认购买界面
图20购买成功
此时确认了购买
5.4图书信息整体浏览界面:
图21图书信息整体浏览
5.5图书信息删除界面:
图22图书信息删除界面
图23密码错误界面
有3次输密码的机会,防止恶意试密码
图24密码多次错误界面
此时按回车会返回到主菜单
图25图书删除界面
此时是密码真确后进入
备注:
接下来选择相应删除方式进入图书删除后和图书购买操作相似,同样可以调用其它函数(已售完图书显示函数)以方便删除,在此就不在重复操作演示。
5.6图书信息保存界面:
图26图书信息保存界面
此时是图书信息变动过
图27重复保存界面
图书信息未变动时进入保存也是此界面
5.7退出程序界面:
图28退出程序界面
此时图书信息变动过,未变动时直接结束程序
5.8图书信息新建界面:
(略)
备注:
图书信息新建功能为附加的功能,程序本身没有要求要有此项功能,在此就不演示。
5.9修改密码界面:
(略)
备注:
修改密码功能为附加的功能,程序本身没有要求要有此项功能,在此就不演示。
6.程序调试与测试
6.1程序调试
(1)各模块分别调试过程及结果。
(1)程序欢迎界面和程序名称界面做起来比较容易,没有出错。
题目显示是老师临时加的一个要求,做起来也没出错。
(2)主菜单界面我是按照老师给的一个参考程序做的,后来自己又优化了一下,没有出问题。
(3)书库信息导入函数voidloadrec()。
书库信息导入到程序中,我是用的链表。
最难得地方就是建立链表,刚开始时,我用两个指针进行操作。
但是存储空间必须刚开始就要申请一个,然后根据文件中的数据,进行循环,动态申请。
这样就会多出一个结点,当最后释放这个节点时,两个指针就操作不了。
后来参考老师的程序,用三个指针,很顺利的就解决了。
如果文件打开失败的话,释放结点就会出错。
比如我的程序(导入书库信息)中的p3->next=NULL,因为文件打开失败,这样就不会进入动态申请存储空间,这样p3->next=NULL就会没有意义。
解决办法:
进入导入书库函数(voidloadrec)时,执行p3=head.即使p3有所指向,就可以解决。
(4)查询函数voidsearch()。
通过书号查询时实现比较容易,找不到时就直接显示找不到,找到就输出,因为一个书号只会对应一本书,循环好做。
而通过书名和作者查询时,可以有多本同名的书或有多本同作者的书。
这时,就需要先做一个循环,看操作者要查询的书名或作者是否存在,若在,就再弄一个循环,从刚才找到的结点后面再开始查找,将与刚才找到的结点相同的信息的结点再输出,直到结点全部检查完。
(5)图书销售函数voidbuy(),为了购买(任何操作者对管理系统来说都是图书购买者)图书操作简便,我将程序限定在只能通过书号来购买图书,因为一个书号只会对应一本书。
但这样就会产生一个问题,如果购买者不知道书号,但知道书名或作者,那他就购买不成图书了。
解决办法:
程序首先默认购买者知道书号,当没有找到购买者所找的书号时,程序就会提示,是否要调用查询功能,当执行调用时,购买者就可以根据自己知道的图书信息(书名或作者),选择相应的查询渠道,这样购买者就可以查看自己要找的书在不在,若在,就可以看着列表信息,重新输入书号进行购买,这样就间接支持了多渠道购买。
为了满足多次购买,我用了一个循环,当购买者想结束购买时,执行相应按键,才可结束购买。
当在最后结束购买时,程序也会提示购买者是否确认购买,此时亦可确认,也可撤销,这样就比较符合实际要就和人性化。
(6)图书信息整体浏览函数voidlist(),实现起来较简单,直接输出结点,直至结束。
(7)图书信息删除函数voiddelet(),进入图书删除需要密码,没有密码者不能进行删除操作,为了防止有人恶意试密码,程序限制了密码输入次数,超过了3次,程序就会返回到主菜单。
程序要求支持通过书号、书名、作者,三种删除方式,没卖完的书不能删除。
通过书号删除时实现起来比较简单,而通过书名和作者删除就很麻烦,因为同一个书名或作者的书可以有多本,而这多本里面可能一部份已尽卖完,有些又没卖完,要删除的结点还可能不止一个。
为了解决这个问题,在通过书号删除时,我通过while()循环,找到要删除的图书书号,找到该结点直接删除,但是通过书名和作者删除时,这种方式就行不通了,由于再删除过程中需要判断要删除的结点的位置,这样就不能同时删除已售完的多本同书名或作者的书。
于是再通过书名和作者删除时,我先创建一个链表,将满足删除要求的图书储存在一起,然后将做一个循环判断,将书库中与该链表储存的相同的图书(信息)一个个删除(删除方式同通过书号删除),直至该链表中的结点走完。
这种方式实现起来简单,但比较耗费程序运行的速度,解决思路不容易想到。
再删除过程中,为了便于删除,防止操作者不知道有哪些书已经卖完,程序可以调用函数voidbover(),显示已经售完的书,看着列表信息进行删除。
(8)保存记录函数voidsave(),实现比较简单。
(9)退出voidexit0(),退出时,为了防止操作者忘记保存记录,在退出程序时,程序会提醒操作者是否需要保存,这时操作者可以以选择保存或不保存,这样在操作者操作失误时,在退出时,也避免了强制保存。
(10)新建书库信息函数和修改密码函数,题目并未作要求,在此就不再介绍。
(2)集成调试过程及结果。
在各模块协调操作时,几乎各个功能模块都需要得到头指针(head),为此我将保存导入书库信息的链表中需要用到的指针定义成全局的,这样便于操作,可防止头指针传错。
为了使在退出和记录保存函数中,在不同的情况下给出不同的提示信息,我定义了一个标志性全局变量intsave_flag=0;/*信息变动标志*/。
在可使书库信息变动的函数中,当书库信息变动成功时,就执行save_flag=1,这样在退出或保存过程中就知道书库信息是否变动过,以便实现相应功能。
在购书过程中,为了间接支持多渠道购书,可以调用查询函数voidsearch(),在主菜单中也可执行查询功能,但是在这两种调用过程中,要求却不是一样的,在购书函数中调用时,查询功能是分次调用的,不能连续执行查询,而且显示的查询信息是不能清屏的,因为操作者需要看着查询得到的列表信息输入书号。
在主函数中执行此项功能时,是要支持连续查询的,而且需要清屏上次执行查询时显示的信息。
为了实现这个要求我定义了一个全局变量intbuy_flag=0,在菜单中执行查询时,首先执行buy_flag=0,在购买图书函数中调用查询功能时,首先执行buy_flag=1.然后通过判断buy_flag的值,在查询功能中实现相应功能。
在删除图书时,在要删除的图书信息没找到时,程序会提醒操作者,是否要显示已售完的图书voidbover(),在调用voidbover()后,操作者可以看着列表图书信息进行删除,此时程序就不能再可以返回到删除方式菜单,为此我定义了一个全局变量intshan_flag=0,当调用了voidbover()后执行shan_flag=1,当删除操作成功后,执行shan_flag=0,这样在显示删除菜单时根据shan_flag的值,就可以完成相应的功能。
结合这些全局变量会使界面变得更流畅和美观。
密码我将其定义成全局变量,这样当我修改密码(题目未作要求,是我自己加的)时,进行删除操作的密码就会跟着改变。
导入书库信息时,程序读文件时会将下一行的回车符读进来,这样就会出现乱码。
如果我删掉文件中的最后一个回车符,导入和整体浏览图书信息会正常,但是当我执行新建图书信息(题目为做要就,是我自己加的)或者图信息变动过后,保存信息时,文件自身又会在数据最后加上一个回车符,后来我上网搜到资料,弄懂了是咋回事。
我们一般读取文件方式:
head=p3=p1=(structbook*)malloc(LEN);/*开辟一个新单元*/
p1->next=NULL;
while(!
feof(fp))
{
n++;
fscanf(fp,"%s%s%s%f%d",p1->bnum,p1->bname,p1->author,&p1->bpay,&p1->benshu);
p2=(structbook*)malloc(LEN);/*继续开辟一个新单元,直到文件读完*/
p1->next=p2;
p3=p1;
p1=p2;
p1->next=NULL;
}
free(p2);p3->next=NULL;/*释放多申请的一个单元*/
这样,当fscanf读到最后一个回车符时,发现文件结束,但这时,信息已经读入。
真确读取:
head=p3=p1=(structbook*)malloc(LEN);/*开辟一个新单元*/
p1->next=NULL;
p7=(structbook*)malloc(LEN);
fscanf(fp,"%s%s%s%f%d",p7->bnum,p7->bname,p7->author,&p7->bpay,&p7->benshu);
while(!
feof(fp))
{
n++;
*p1=*p7;
p2=(structbook*)malloc(LEN);/*继续开辟一个新单元,直到文件读完*/
p1->next=p2;
p3=p1;
p1=p2;
p1->next=NULL;
fscanf(fp,"%s%s%s%f%d",p7->bnum,p7->bname,p7->author,&p7->bpay,&p7->benshu);
}
free(p2);p3->next=NULL;/*释放多申请的一个单元*/
利用中间的一个变量p7做一个临时存储空间,文件没结束,再将其信息给p1。
(3)功能调试过程及结果。
首先根据题目,新建一个文件,执行程序,看程序是否能够正常读取文件。
读取正常。
分别执行不同的函数看,是否能正常运行。
各个程序单独执行正常。
在运行一次的情况下,连续执行不同函数,检查是否有逻辑错误。
在执行了相应的函数后,对比文件,看文件是否按程序操作的结果,正确改变了。
将文件删除,看程序是否会给出正确提示,并且限制某些没有文件不能实现的功能。
将文件置空,看是否会给出相应提示以及程序是否运行正常。
6.2程序测试
各模块测试用例数据及结果
显示结果一致(图书整体浏览函数)
与文件结果一致(图书查询函数)
通过书名查找结果
调用查询功能购买图书
购买成功后与前面文件内容对比,确实少了一题本(鬼谷子)
通过书名删除
删除成功后与前面的文件对比,显示确实删除了
测试中出现的问题的原因和分析
在测试数据过程中,若发现测试结果与文件中结果不相符
检查在执行相关操作后,是否确认了该操作,比如在购书过程中,最后你是否确认了购买。
检查在退出程序时是否保存了修改记录。
检查文件是否一直没关过,因为信息变动后,文件如果一直没关,文件中显示的依旧是操作前的结果。
7.问题与不足
(1)需求分析中存在的问题和分析:
该程序不支持插入新图书,不支持统计销售收入,不支持修改图书信息,与实际不符。
程序最后我虽然加了一个图书信息新建功能和修改密码功能,但图书新建功能,不能完全识别操作者输入的错误信息。
(2)概要设计中存在的问题和分析:
全局标志性变量用的太多,在主体函数中定义变量时,容易与全局标志性产生混淆。
全局指针也用的太多,虽然这样避免了传指针出错,但没有锻炼我们传参数的能力。
(3)详细设计中存在的问题和分析:
在图书购买过程中,不能够直接支持通过书名和作者购买图书,而且也不支持一次性购买多本,购买多本只能通过连续购买。
(4)代码编制中存在的问题和分析:
由于程序中用了较多的循环和判断,花括弧({})较多,容易缺少或多出花括弧。
ALT+F8不仅能将代码自动整理成微软的cpp文件格式,而且它还是检查花括弧是否缺少或多出的有力工具。
(5)调试和测试中存在的问题和分析:
在编写程序代码是,要注意全局变量和局部变量,防止二者混淆。
当文件打开失败时要注意指针是否还有确定的指向,比喻在导入书库信息函数voidloadrec()中,当文件打开失败时,p3->next=NUU就没有意义,在这之前就需要为p3申请一个空间。
8.建议
课设题目有些地方自相矛盾(不是我的题目),建议老师能花点时间将课设题目中有些不合理的地方改正一下。
时间安排上,刚开始时觉得
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课程设计 图书 销售 管理 系统