C课程设计:图书销售系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

山东大学威海分校C/C++程序设计
课程名称:C/C++程序设计
专题:图书销售系统
姓名:田玉针
学号:200900800170
专业:09通信工程
指导老师:信工程
图书销售管理系统设计
一、设计要求:
图书信息包括:序号、书名、作者、出版单位、价格。

设计一图书销售管理系统,使之能提供以下功能:
1、系统以菜单方式工作
2、图书信息录入功能(图书信息用文件保存)--输入
3、图书信息的删除与修改功能
4、图书信息浏览功能--输出
5、查询功能--算法:按书名/作者查询
6、排序功能--算法
按书名排序
按价格排序
7、图书购买功能:统计选购图书的总价,给出清单,屏幕输出参考以下的实际购书单(供参考,输出样式可自行设计):
二、设计思路
考虑到自己是非软件专业,没有系统的学过数据库、数据结构等专业性较强的知识,整个程序设计我采用函数调用的方式来实现设计要求的功能。

这样做的优点是设计较简单,容易操作。

主函数控制着整个系统的执行流程,使系统菜单可以循环执行。

菜单提供一个可以选择任何一个功能的选择窗口。

供用户选择需要的执行。

Switch语句可以很方便的解决多分支选择问题。

根据设计要求可知,程序需要数据的录入和调用。

因此需要有数据录入函数,然而录入的数据放在哪里呢?故此,需要设计保存文件函数和打开文件函数。

保存文件函数,把内存中结构体得信息输出到TXT文件中,数据以文件的形式存放在磁盘上,方便以后需要时再从磁盘中输入到计算机内存。

保存函数和打开函数都用fopen命令。

打开文件函数,把文件的信息打开到一个结构体数组中。

调用已保存的数据。

录入函数,调用scanf函数进行数据的输入,再调用保存文件函数即可将录入的信息保存到文件中。

输出函数提供对图书信息的检索,浏览图书信息。

查询函数,用户可以输入图书的名字或者作者的名字对图书进行检索,查看图书的价格、库存等信息。

删除和修改函数,提供对图书信息的删除和修改功能。

该函数可以根据用户输入的信息与保存的信息进行比较,如果匹配则对该信息做修改或删除操作,如果没有匹配则输出“此书不存在”。

排序函数,提供图书信息的检索,按用户选择的条件(书名或价格)进行排序。

购买函数,统计选购的图书总价,列出清单,对库存不足的书或不存在的书会有提示信息。

可以统计用户订购的信息,也可以取消订购。

在我的设计中,各个功能之间基本是相对独立的,他们都是在主函数的控制、调用下,分工合作的。

程序根据用户的选择调用不同的函数,从而实现不同的功能。

程序以函数块儿的形式呈现,这样做不仅提高了程序的可读性,而且便于程序的修改,方便查找漏洞。

三、关键功能和函数流程图
1.总程序
整体程序是用户通过菜单,选择要执行的功能,程序通过switch语句经过选择,选择后继续执行相应函数下的其他功能,直到结束程序,如果选择退出系统就直接跳到结束程序。

整个程序的完整流程图:
2.open函数
对library文件读写之前应该“打开”该文件,在使用结束之后应该“关闭”该文件。

所谓“打开”是指为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区(用来暂时存放输入输出的数据)。

在编写程序时,在打开文件的同时,指定一个指针变量指向该文件(FILE *fp;),建立起指针变量与文件之间的联系,这样就可以通过该指针变量对文件进行读写了。

所谓“关闭”是指撤销文件信息区和文件缓冲区(fclose(fp);),使文件指针变量不再指向该文件。

相应的程序如下:
void open()//打开图书信息
{
FILE *fp;
if((fp=fopen("library.txt","r+"))==NULL)
{
fp=fopen("library.txt","w+");
}
fread(&library.count,sizeof(int),1,fp);
fread(library.book,sizeof(library.book[0]),library.count,fp);
fclose(fp);
}
程序执行的流程图如下图所示:
3.save函数
先检查打开的操作是否有错,如果有错就在终端上输出“cannot open this file”。

FILE *fp;
if((fp=fopen("library.txt","wr+"))==NULL)
{
printf("\ncannot open file!\n");
return;
}
如果打开成功,函数的返回值就是该文件所建立的信息区得起始地址,把它赋给指针变量fp,将结构体library中的数据写到fp所指向的文件中,最后关闭指针即可。

4.putin函数
对library文件读写之前应该“打开”该文件,调用open()函数打开library 文件。

图书信息录入之前应该有提示信息,调用printf函数用来实现数据输出的功能,输出提示信息到屏幕。

通过多次使用scanf函数,将图书的图书号、名字、作者、出版社、出版时
间、价格、库存量存入到结构体library.book中。

每执行一次录入后library.count 自动加1,统计录入的图书种类。

通过语句scanf("%d",&y);
if (y!=1)
{ y=0;
break; }
}
可以实现多次录入(输入1)和退出录入(选择0),录入之后执行save函数,可以将输到结构体中的数据保存到library文件中,存储到磁盘中,以备之后的调用。

Putin函数程序主要代码如下:
void putin() /*定义录入函数*/
{
int y=1;
open();
while(y)
{
printf("\n\t请输入您的书籍的图书号:");
scanf("%s",library.book[library.count].number);
printf("\t请输入书名:");
scanf("%s",library.book[library.count].name);
printf("\t请输入作者名:");
scanf("%s",library.book[library.count].author);
printf("\t请输入出版社:");
scanf("%s",library.book[library.count].publish);
printf("\t请输入出版时间:");
scanf("%s",library.book[library.count].time);
printf("\t请输入该书的价格:");
fflush(stdin); //清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件
scanf("%f",&library.book[library.count].price);
printf("\t请输入该书的库存量:");
scanf("%d",&library.book[library.count].kucun);
library.count++;
printf("\n是否继续录入(1.继续;0,退出录入):");
fflush(stdin);
scanf("%d",&y);
if (y!=1)
{
y=0;
break;
}
}
save();
}
5.lookup函数
通过循环函数可以对所有的图书信息进行浏览,对结构体中的信息进行循环输出,直到所有的图书的信息全部输出为止。

程序主要代码如下:
void lookup()
{
open();
system("cls"); //清除
printf("\n\n\t图书号\t图书名\t作者名\t出版社\t出版日期\t图书价格\t库存量\n");
for (int i=0;i<library.count;i++)
{ printf("\t%s\t%s\t%s\t%s\t%s\t\t%6.2f\t\t%d\n",library.book[i].number,library.book[i].na me,library.book[i].author,library.book[i].publish,library.book[i].time,library.book[i].price,library.b ook[i].kucun);
}
fflush(stdin);
getchar();
}
输出效果如下:
6.search函数
查询函数,用户可以输入图书的名字或者作者的名字对图书进行检索,查看图书的价格、库存等信息。

用户可以通过键盘输入自己想要的查询方式,按作者查询和按书名查询。

此功能可以通过switch语句进行实现。

程序代码如下:void search() /*定义查询函数*/
{
int a;
system("cls");
printf("\n\t\t请选择查询方式:");
fflush(stdin);
scanf("%d",&a);
switch(a)
{
case 1: search_by_name();
break;
case 2: search_by_author();
break;
case 0: return;
}
}
程序运行结果如下图:
每一种查询方式都用单独的函数实现。

按作者查询时,用户输入自己要查询的作者的名字,通过语句strcmp(s3,library.book[i].author)==0判断输入的作者是否存在,如果存在则输出该作者所有书籍的信息,如果不存在输出提示语句“不存在此作者的书籍!”按书名查询和按作者查询的原理是一样的。

7.order函数
排序函数,提供图书信息的检索,按用户选择的条件(书名或价格)进行排序。

通过switch语句实现排序方式的选择。

代码如下:
scanf("%d",&a);
switch(a)
{ c ase 1: order_by_name();
break;
case 2: order_by_price();
break;
case 0: return;
}
每种排序方式用不同的函数实现,按价格排序的函数,利用选择法进行排序。

k用来存放最小的元素的序号,将第i个元素与其后各个元素比较,如果第j个元素比第k个元素小,把当前最小元素的序号j保存在k中,将最小元素与b[i]对换。

这样就可以实现升序排序,主要代码如下:
float s[100];
int i,j,k,m,b[100];
open();
system("cls");
for(i=0;i<library.count;i++)
{ s[i]=library.book[i].price;
b[i]=i; }
for(i=0;i<library.count-1;i++)
{ k=i;
for(j=i+1;j<library.count;j++)
{
if( s[b[k]] > s[b[j]] ) k=j;
}
if(k!=i)
{ m=b[k];
b[k]=b[i];
b[i]=m;
}
}
按书名排序,是通过比较书名首字母的ASCII码来进行排序,排序的方式与按价格排序大同小异,这里就不重复说明了。

主要代码如下:
char s[100][30];
int i,j,k,m,b[100];
open();
system("cls");
for(i=0;i<library.count;i++) /*输入各书名,并记录他们在数组中的行号*/ {
strcpy(s[i],library.book[i].name);
b[i]=i;
}
for(i=0;i<library.count-1;i++) /*选择法从小到大排序*/
{
k=i;
for(j=i+1;j<library.count;j++)
{
if(strcmp(s[b[k]],s[b[j]])>0) k=j; /*记录当前最小书名的行号b[k]*/ }
if(k!=i)
{
m=b[k]; /*最小书名的行号b[k]与b[i]交换位置*/
b[k]=b[i];
b[i]=m;
}
}
8.del函数
删除函数可以根据客户需求删除图书信息,用户输入要删除的图书的序号,通过语句(strcmp(number,library.book[i].number)==0判断输入的图书序号是否存在,如果不存在输出提示信息“此书不存在!”,如果存在,进一步确认是否要删除图书信息如果选择是,执行删除功能,每删除一个图书信息,library.count自动减一,以保证程序的正确性。

每次执行后都要对机构体的信息保存到文件中,以备以后的调用。

9.update函数
修改图书信息函数可以对以保存的图书信息进行修改,通过输入的要修改的图书序号,可以对该图书的所有信息进行修改,程序会将修改之后的信息保存到library机构体中,最后通过调用save函数将修改后的信息保存到文件中。

10.shopping函数
购买函数,统计选购的图书总价,列出清单,对库存不足的书或不存在的书会有提示信息。

可以统计用户订购的信息,也可以取消订购。

程序先对输入的书名进行核对,如果该书不存在,则输出提示信息“此书不存在!”。

如果此书不存在则会提示用户输入订购的数量,如果数量大于库存数量则会出现提示信息“库存不足!”,之后返回订购主页,输入订购信息。

代码如下:if(shopping_book[i++].count>library.book[m].kucun)
{
printf("库存量不足!");
fflush(stdin);
getchar();
shopping();
}
如果库存足够的话,接着执行下一条指令,输出图书的详细信息、数量以及总共的价格。

程序会提示用户是否确定要购买,如果选择否的话,用户可以重新输入想要订购的信息,如果选择是的话程序会要求客户输入订购的地址和联系方式。

printf("\n\t是否继续购买?(1.继续;0.提交):");
fflush(stdin);
scanf("%d",&y);
if (y!=1)
{
system("cls");
printf("\n\n\n\n\n\t\t\t\t购书清单\n");
printf("============================================================= ============\n");
printf("图书号\t图书名\t作者名\t出版社\t图书单价\t订购数量\t总计价格\n");
printf("============================================================= ============\n");
for(int j=0;j<i;j++ )
{
for(int k=0;k<library.count;k++)
if(strcmp(shopping_book[j].name,library.book[k].name)==0)
{
flag=0;
library.book[k].kucun=(library.book[k].kucun)-(shopping_book[j].count);
printf("%s\t%s\t%s\t%s\t%6.2f\t\t%d\t\t%6.2f\n",library.book[k].number,
library.book[k].name,library.book[k].author,library.book[k].publish,
library.book[k].price,shopping_book[j].count,jj=shopping_book[j].count*library.book[k].price);
zongjia=zongjia+jj;
printf("-------------------------------------------------------------------------\n");
}
else
;
}
printf("购书总价为%.2f\n",zongjia);
printf("\n\n\n\t确认要购买吗?(1.确认;0.重新订购):");
int b;
scanf("\t\t%d",&b);
if(b!=1)
{
shopping();
}
if(b)
{
printf("\n\t请输入收货地址:");
scanf("%s",add);
printf("\n\t请输入联系电话:");
scanf("%s",tele);
printf("\n\n\t已成功订购!");
fflush(stdin);
getchar();
break;
}
}
程序运行结果如下图:
11.main函数
主函数控制着整个系统的执行流程,使系统菜单可以循环执行。

菜单提供一个可以选择任何一个功能的选择窗口。

供用户选择需要的执行。

Switch语句可以很方便的解决多分支选择问题。

主要程序如下:
int a;
do
{
system("cls");
printf("\t\t请输入0--7序号: ");
fflush(stdin);
scanf("%d",&a);
switch(a)
{
case 1: putin();
break;
case 2: lookup();
break;
case 3: search();
break;
case 4: del();
break;
case 5: update();
break;
case 6: order();
break;
case 7: shopping();
break;
case 0: printf("\n\n退出\n\n");
break;
default: printf("\n序号不对\n");
fflush(stdin);
getchar();
}
}while(a!=0);
save();
运行结果如下图:
四、增加功能
在程序设计要求的基础上,根据实际需求,在图书信息里我添加了库存量,而且,在图书订购之后,库存量会根据客户订购的情况自动进行修改,保证了库存量得准确性。

在订购这一功能中,我增加了确定是否订购这一功能,客户可以重新填写订购的书名和数量。

避免不必要的错误。

五、跟踪调试
程序设计出来之后总是会有很多错误和纰漏,在运行之后难免会有大大小小的问题,只有通过一次次的运行,一次次的修改程序才能得到较为完善的程序。

我不能说我的程序很完美,但是在我不断的调试之下,它能够实现老师要求的基本功能,没有出现大的错误。

主程序较为简单,是switch语句的运用,很容易实现。

打开和保存程序是利用文件保存数据,此程序中用到的部分较为简单,也是很容易实现。

录入程序中,一开设计的程序一次只能保存一本书的信息,之后就跳到主界面。

考虑到录入图书信息不回只有一本,我又对程序进行了修改,使得程序可以根据用户的要求选择继续录入还时直接跳到主页面。

这样方便了图书信息的录入。

查询函数是将存到文件中的图书信息读到屏幕中,也是较为简单的。

排序函数中,按价格排序的较为简单,利用选择法进行升序排序。

一开始我不知道如何对书名进行排序,在和同学们讨论之后,我了解到可以对书名的ASCII码进行比较大小,然后进行排序。

订购函数是最难的一部分,因为它涉及到是否有这本书,有这本库存不足又该怎么办等一系列问题。

一开始总是不能很好的判断书籍是否存在、库存是否足够,会出现很多问题,经过多次调试和修改后,终于可以很好的实现这部分的功能了。

六、心得体会
通过这次实习,让我初步有了利用C编写系统的能力,我对很多的函数有了新的认识,也学会了运用多种函数,我也明白了编写软件的基本过程,和基本方法。

编写软件的过程中我又学到了曾经自己不知道的函数或是自己不会的函数的用法。

特别是文件的开启和关闭,读与写。

这次课程设计课总的来说让我受益匪浅。

在软件的设计过程中遇到了很多的困难。

在软件一次一次的调试失败下,曾经想过要放弃。

我最后还是让自己坚持了下来,毫不畏惧困难,在同学的帮助与讲解下我总算是顺利的完成了软件的设计。

在程序的编写过程中我发现我自己有很多的知识漏洞和缺陷,需要进一步努力学习来完善自己。

在这几天的编写过程中我对c语言有了更进一步的认识和了解。

此次编程过程的经验和知识肯定能促进我以后的学习。

此次课程设计不仅给了我很多很好的经验,也然我体会到了失败时的焦急和难受,也体会到了成功时的兴奋与喜悦。

在此我向在此次课程设计时对我伸出援助之手的张老师,还有帮助我的同学们。

缺少了这些也许我的程序就无法调试完成。

谢谢老师和同学们的帮助与讲解。

相关文档
最新文档