北京联合大学c语言实训 商店商品管理信息系统.doc
北京联合大学课 程 设 计 报 告课程名称: C语言程序设计实训 项目名称: 商店商品管理信息 学 院: 自动化学院 专 业:信息处理与智能技术 姓 名: 赵大帅 李志磊 冯麒麟 学 号: 指导教师: 成 绩: 2011年6月21日目 录第一部分 课程设计题目与要求1. 问题提出2.功能要求3任务分工第二部分 设计实训题目功能1. 总体设计2. 算法设计3. 数据结构4. 程序代码设计5. 测试与调试第三部分 课程设计总结1. 个人总结2. 结束语附录A 程序清单附录B 用户使用说明书参考文献第1部分 实训题目与要求1. 问题提出: 某商店每天有进货、售货、统计销售额、计算毛利率、查看商品剩余量等业务,所以人工管理是一件非常繁琐的事情,为了快速有效的管理,该商店提出要编制一个计算机管理软件。 2. 功能要求: 在主菜单中选择:1. 创建商品档案。每一个商品的信息包括编号、品名、进价、售价、进货量、销售量、销售额、剩余数、毛利。2. 进入子菜单,并编辑商品信息。例如,向商品档案添加新商品,删除原有商品,处理员有商品的新进货量、新销售量、报废量。在子菜单中选择4,返回主菜单;选择0,退出整个系统。3. 统计销售额情况。在此项中统计每种商品的销售额、剩余数、毛利(毛利=销售额-进价×销售量)。4. 进入子菜单,并查询商品信息。如根据品名、剩余数(小于5大于20)进行查询。在子菜单中选择3,返回主菜单;选择0,退出整个系统。5. 进入子菜单,并显示商品信息。显示方式有3 种,即按原来商品顺序显示、按销售额从高到低的顺序显示、按毛利从高到低的顺序显示,由于商品较多,所以要求分屏显示。在子菜单选择4,返回主菜单;选择0,退出整个系统。6. 创新功能给商品分类。7. 主菜单中选择0:显示结束信息(如“感谢使用本软件!已正常退出,按任意键结束。”),按任意键后,退出本系统。3. 任务分工:(1): 编辑商品信息; 创新功能:给商品分类的主函数、给商品分类中的按生活用品分。(2)郭欣桐:创建商品档案、查询商品信息; 创新功能:给商品分类中的按食品分。(3)胡岩松:统计销售情况、显示商品信息; 创新功能:给商品分类中的按学习用品分。注:流程图与实训报告由三个人共同分担完成。第2部分 设计实训题目功能1.总体设计: (1)模块设计:如下图菜单:-| 请输入选项编号(0-6) |-| 1创建商品档案 | 2编辑商品信息 | 3统计销售情况 | 4查询商品信息 | 5显示商品信息 | 6创新功能 | 0退出系统 |-*| 请输入选项编号(0-4) |*| 1添加新商品 | 2删除原有商品 | 3修改原有商品信息 | 4返回 | 0退出系统 |*| 请输入选项编号(0-3) |*| 1按品名查询 | 2按剩余数查询 | 3返回 | 0退出系统 |*| 请输入选项编号(0-4) |*| 1按原来顺序显示 | 2按销售额高低显示 | 3按毛利高低显示 | 4返回 | 0退出系统 |*(2)定义各函数的主要功能: 主函数:将需要的函数都放在主函数中,当需要不同的函数的时候便可用主函数调用不同的函数,运用主函数可以方便调用其它函数。 创建商品档案函数:向原有商品档案中添加新的商品以及有关信息。 编辑商品信息函数:可以添加新商品、删除原有商品、修改原有商品信息。 统计销售情况函数:可以统计每种商品的销售额、剩余数、毛利。 查询商品信息函数:可以查询商品信息,分为按品名查询、按剩余数查询。 显示商品信息函数:可以显示出商品信息,按原来顺序显示、按销售额高低显示、按毛利高低显示。 创新功能函数:给商品分类可以将商品分为3类,按生活用品分类、按食品分类、按学习用品分类。(3)程序模块图:2.算法设计:(1)显示子菜单。用printf函数将菜单项一项项地打印到屏幕上,界面中的边框可以通过多个printf语句输出的“|”和“-”拼接起来。(2)菜单项的选择。菜单应根据用户的选择做出不同的反应,因此需要使用分支结构实现选择选项的功能。鉴于目前仅仅是做主菜单,还不能实现各菜单项的具体功能,因此该程序中暂时根据用户的选择,输出对应菜单的编号。根据题意,主菜单含有7个菜单项,属于多分支条件判断,使用带break的switch语句最为合适。需要注意的是,还要处理当用户输入错误时的情况。(3)重复显示主菜单。因为本实例具有重复选择主菜单的功能,因此需要使用循环结构。在本实例中主菜单至少显示一次,然后才判断是否继续选择主菜单,所以使用do-while循环比较好,因为do-while循环是先执行循环体,然后在判断表达式。 作为菜单,应该给用户一个正常的出口,即满足一定条件时退出程序。为了给用户提供方便,我们采用人机对话形式,当用户选择某一菜单项后,系统立即完成相应的功能,然后询问用户是否需要继续选择,只要用户选择继续(输入y或Y),主菜单就在屏幕上反复出现,只有单用户选择不再继续(输入n或N)时,才可以退出主菜单。除此之外,为了使用方便,在主菜单中还特设0选项,选择它也能正常退出程序。 为了实现上述功能,有关语句都应放在do-while循环体中。 设计算法时应考虑如何时程序具有容错能力。例如,当用户在应答是否继续时,如果输入的是合法数据(即y、Y、n或N),则程序继续下一步操作;如果输入的是非法数据(即y、Y、n或N以外的字符),则应让用户重新输入,这时需要在是否继续的问题上加一个循环判断,这种功能常用do-while实现。(4)流程图(如下图所示):主模块流程图创建商品档案模块的流程图编辑商品信息模块的流程图添加新商品模块的流程图删除原有商品模块的流程图修改原有商品信息流程图统计销售情况的流程图查询商品信息的流程图按品名查询流程图按剩余数查询流程图显示商品信息流程图按原来顺序显示模块的流程图按销售额高低显示的流程图按毛利高低显示的模块创新功能流程图按生活用品分类流程图注:按食品和学习用品分类似3.数据结构:struct goodschar bh10; char pm30;float jj;float sj;int jhl;int xsl;float xse;int sys;float ml;此结构体为存放商品信息,编号bh10,商品名pm30,进价jj,售价sj,进货量jhl,销售量xsl,销售额xse,剩余数sys,毛利ml.4. 程序代码设计:void mycreate() int i=1;float x,y,z,t; struct goods temp=0;FILE *fp=NULL;fp=fopen("d:cwzgoods.txt","w");if(fp=NULL) printf("n 打开文件夹失败!n");return;system("cls");printf("n 请输入第1个记录:n");printf(" 编号(用#结束输入):");do gets(temp.bh); while(strcmp(temp.bh,"")=0);printf(" 品名(用#结束输入):");gets(temp.pm);printf(" 进价(用#结束输入):");scanf("%f",&x);temp.jj=x;printf(" 售价(用#结束输入):"); scanf("%f",&y);temp.sj=y;printf(" 进货量(用#结束输入):");scanf("%d",&temp.jhl);printf(" 销售量(用#结束输入):");scanf("%d",&temp.xsl);printf(" 销售额(用#结束输入):");scanf("%f",&z);temp.xse=z;printf(" 剩余数(用#结束输入):");scanf("%d",&temp.sys);printf(" 毛利(用#结束输入):");scanf("%f",&t);temp.ml=t;while(temp.bh0!='#'&&temp.pm0!='#') fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",temp.bh,temp.pm, temp.jj,temp.sj,temp.jhl,temp.xsl,temp.xse,temp.sys,temp.ml); i+; printf("n 请输入第%d个记录:n",i); printf(" 编号(用#结束输入):"); do gets(temp.bh); while(strcmp(temp.bh,"")=0); printf(" 品名(用#结束输入):"); gets(temp.pm); printf(" 进价(用#结束输入):"); scanf("%f",&x); temp.jj=x; printf(" 售价(用#结束输入):"); scanf("%f",&y); temp.sj=y; printf(" 进货量(用#结束输入):"); scanf("%d",&temp.jhl); printf(" 销售量(用#结束输入):"); scanf("%d",&temp.xsl); printf(" 销售额(用#结束输入):"); scanf("%f",&z); temp.xse=z; printf(" 剩余数(用#结束输入):"); scanf("%d",&temp.sys); printf(" 毛利(用#结束输入):"); scanf("%f",&t); temp.ml=t;fclose(fp);void myedit()char choose='0',yes_no='0' do myprint1();choose=getch();switch(choose)case '1': myadd(); break; case '2':mydelete(); break; case '3': mymodify(); break; case '4': return; case '0': exit(0); default : printf("n %c为非法选项!n",choose);if(choose='0') break;printf("n 要继续选择吗(Y/N)?n");do yes_no=getche( ); while(yes_no!='Y' && yes_no!='y' && yes_no!='N' && yes_no!='n'); while(yes_no='Y' | yes_no='y');void myadd()char c='0'int n=0;float x,y,z,t;struct goods temp=0,recordN=0,*p=NULL;FILE *fp=NULL;fp=fopen("d:cwzgoods.txt","r");if(fp=NULL)printf("n 打开文件失败!n");return;p=record;printf("原有商品信息为:n");while(feof(fp)=0)fscanf(fp,"%s%s%f%f%d%d%f%d%f",p->bh,p->pm,&x,&y,&p->jhl,&p->xsl,&z,&p->sys,&t);printf("%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,x,y,p->jhl,p->xsl,z,p->sys,t);p->jj=x;p->sj=y;p->xse=z;p->ml=t;p+;n+;getchar();fclose(fp);doprintf("n 请输入新记录的编号:");dogets(temp.bh);while(strcmp(temp.bh ,"")=0);printf(" 请输入新记录的品名:");gets(temp.pm );printf(" 请输入新记录的进价:");scanf("%f",&temp.jj);printf(" 请输入新记录的售价:");scanf("%f",&temp.sj);printf(" 请输入新记录的进货量:");scanf("%d",&temp.jhl);printf(" 请输入新记录的销售量:");scanf("%d",&temp.xsl);printf(" 请输入新记录的销售额:");scanf("%f",&temp.xse);printf(" 请输入新记录的剩余数:");scanf("%d",&temp.sys);printf(" 请输入新记录的毛利:");scanf("%f",&temp.ml);for(p=record;p<record+n;p+)if(strcmp(temp.bh,p->bh )=0)printf(" 编号重复,要重新输入吗(Y/N)?");doc=getche();while(c!='Y'&&c!='y'&&c!='N'&&c!='n');putchar('/n');break;if(p=record+n) *p=temp;break;while(c='y'|c='Y');fp=fopen("d:cwzgoods.txt","w");if(fp=NULL)printf("n 打开文件失败!n"); return; for(p=record;p<record+n+1;p+)fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,p->jj,p->sj,p->jhl,p->xsl,p->xse,p->sys,p->ml);fclose(fp);void mydelete()char c='0'printf("n 按商品编号删除(b),还是按品名删除(p)?");c=getche();if(c='b'|c='B') del_bh();else if(c='p'|c='P') del_pm();else printf("n 非法字符!n");void del_bh()char tempbh10=""int n=0;float x,y,z,t;struct goods recordN=0,*p=NULL,*k=NULL;FILE *fp=NULL;fp=fopen("d:cwzgoods.txt","r");if(fp=NULL)printf("n 打开文件失败!n");return;p=record;printf("n");while(feof(fp)=0)fscanf(fp,"%s%s%f%f%d%d%f%d%f",p->bh,p->pm, &x,&y,&p->jhl,&p->xsl,&z,&p->sys,&t);p->jj=x,p->sj=y,p->xse=z;p->ml=t;printf("%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm, x,y,p->jhl,p->xsl,z,p->sys,t);p+;n+;fclose(fp);printf("n 请输入要删除的商品编号:");gets(tempbh);for(k=record;k<record+n;k+)if(strcmp(tempbh,k->bh)=0) break;if(k<record+n)for(p=k;p<k+n-1;p+)*p=*(p+1);fp=fopen("d:cwzgoods.txt","w");if(fp=NULL)printf("n 打开文件失败!n");return;for(p=record;p<record+n-1;p+)fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,p->jj,p->sj,p->jhl,p->xsl,p->xse,p->sys,p->ml);fclose(fp);else printf("n 无此商品!n");fp=fopen("d:cwzgoods.txt","w");if(fp=NULL)printf("n 打开文件失败!n");return;for(p=record;p<record+n-1;p+)fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,p->jj,p->sj,p->jhl,p->xsl,p->xse,p->sys,p->ml);fclose(fp);void del_pm()char temppm10=""int n=0;float x,y,z,t;struct goods recordN=0,*p=NULL,*k=NULL;FILE *fp=NULL;fp=fopen("d:cwzgoods.txt","r");if(fp=NULL)printf("n 打开文件失败!n");return;p=record;printf("n");while(feof(fp)=0)fscanf(fp,"%s%s%f%f%d%d%f%d%f",p->bh,p->pm, &x,&y,&p->jhl,&p->xsl,&z,&p->sys,&t);p->jj=x,p->sj=y,p->xse=z;p->ml=t;printf("%4s%12s%8.1f%8.1f%8d%10d%10.1f%8d%10.1fn",p->bh,p->pm, x,y,p->jhl,p->xsl,z,p->sys,t);p+;n+;fclose(fp);printf("n 请输入要删除的商品名:");gets(temppm);for(k=record;k<record+n;k+)if(strcmp(temppm,k->pm)=0)break;if(k<record+n)for(p=k;p<k+n-1;p+)*p=*(p+1);fp=fopen("d:cwzgoods.txt","w");if(fp=NULL)printf("n 打开文件失败!n");return;for(p=record;p<record+n-1;p+)fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,p->jj,p->sj,p->jhl,p->xsl,p->xse,p->sys,p->ml);fclose(fp);else printf("n 无此商品!n");fp=fopen("d:cwzgoods.txt","w");if(fp=NULL)printf("n 打开文件失败!n");return;for(p=record;p<record+n-1;p+)fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,p->jj,p->sj,p->jhl,p->xsl,p->xse,p->sys,p->ml);fclose(fp);void mymodify()char c='0'int n=0;float x,y,z,t;struct goods recordN=0,temp=0,*p=NULL,*find=NULL;FILE *fp=NULL;fp=fopen("d:cwzgoods.txt","r");if(fp=NULL)printf("n 打开文件失败!n");return;p=record;printf("n");while(feof(fp)=0)fscanf(fp,"%s%s%f%f%d%d%f%d%f",p->bh,p->pm, &x,&y,&p->jhl,&p->xsl,&z,&p->sys,&t);p->jj=x,p->sj=y,p->xse=z;p->ml=t;printf("%4s%12s%8.1f%8.1f%8d%10d%10.1f%8d%10.1fn",p->bh,p->pm, x,y,p->jhl,p->xsl,z,p->sys,t);p+;n+;fclose(fp);if(fp=0)printf("n 文件中无记录!n");return;printf("n 请输入需要修改的商品编号:");gets(temp.bh);for(p=record;p<record+n;p+)if(strcmp(temp.bh,p->bh)=0)find=p;break;if(p=record+n)printf("n 无此物!n");return;doprintf(" 请输入正确的商品编号:");dogets(temp.bh);while(strcmp(temp.bh,"")=0);printf(" 请输入正确的品名:");gets(temp.pm);printf(" 请输入正确的进价:");scanf("%f",&temp.jj);printf(" 请输入正确的售价:");scanf("%f",&temp.sj);printf(" 请输入正确的进货量:");scanf("%d",&temp.jhl);printf(" 请输入正确的销售量:");scanf("%d",&temp.xsl);printf(" 请输入正确的销售额:");scanf("%f",&temp.xse);printf(" 请输入正确的剩余数:");scanf("%d",&temp.sys);printf(" 请输入正确的毛利:");scanf("%f",&temp.ml);for(p=record;p<record+n;p+)if(strcmp(temp.bh,p->bh)=0)&&(p!=find)printf("n 商品编号重复,要重新输入吗(Y/N)?");doc=getche();while(c!='Y'&&c!='y'&&c!='N'&&c!='n');putchar('n');break;if(p=record+n)*find=temp;break;while(c='y'|c='Y');fp=fopen("d:cwzgoods.txt","w");if(fp=NULL)printf("n 打开文件失败!n");return;for(p=record;p<record+n;p+)fprintf(fp,"%4s%12s%8.1f%8.1f%8d%8d%8.1f%8d%8.1fn",p->bh,p->pm,p->jj,p->sj,p->jhl,p->xsl,p->xse,p->sys,p->ml);fclose(fp);完整程序请参见附录A5.测试与调试: 一个程序虽然经过多次的检查修改,编译连接甚至可以运行,但这时还不能断定该程序就是正确的,因为程序中可能存在逻辑错误,而这些错误往往很难用眼睛检查出来,因此需要进行测试与调试。 测试与调试的首要工作是,用适合的测试数据检查程序的正确性和完整性。按照题目的具体情况,在需要输入数据的地方,选定两大类的测试数据,一类为合法数据,用来测试程序的正确性和完整性;另一类为非法数据,用来测试程序的容错能力和健壮性。 测试与调试的下一个工作是,对找到的错误查出原因,并排除错误。由于这项工作一般很难,所以需要调试程序的技巧。(1) 选定合适的调试用例;(2) 发现错误;(3) 查出错误原因,并排除错误。当调试比较长的程序时,经常将设置断点的方法将程序分为若干个部分,再逐步减少错误出现的程序范围,最后需要仔细检查的部分用单步执行的方法调试。调试程序可用的方法:临时加打印语句,将所要观察的数据显示在屏幕上;用F8或F7键单步执行程序;用Ctrl+F8键设置断点;综合使用以上方法。第3部分 实训总结1. 个人总结:(1) 通过这次实训,我收获了很多,不仅巩固了这一学期所学到的内容,而且还学到了许多新的知识。如浮点型变量不能直接读取,需要一个中间变量才可以。这次实训我们做的是商店商品管理系统,第一次做系统遇到了很多问题,在克服困难过程中,不仅增长了我的见识,关键煅炼了我的能力,自己分析问题和事件的能力;开发了我们活跃的思维,在老师的指导下,取得进步,使我在诸多方面得到了提升。通过我们的小组合作,在辛苦的付出后,我们也收获了丰硕的果实。在实训的开始,我们盲目编程序,结果运行以后连续出错,后来我们又重新对照课本和实训书,并在老师和同学的帮助下才一一解决。其实我们犯错的地方经常把浮点型变量写成%d之类的错误,但是随着错误的解决,我们在不断进步,心中欣喜之余,也对C语言有了更加系统的了解。在画流程图的过程中,第一次接触,开始还十分新奇,之后才一点一点明白了其实并没有那么简单,一个很短的线条有时也需要画很多次,但我们并没有放弃,尽管有时会有些不耐烦,但我们还是坚持认真的完成。而且这次实训给了我们亲自动手实践的机会,大大增强了我对知识的应用能力。它使我们平时所学的理论切实应用到了实际。这次实训还让我明白了一些道理,无论做什么,我们都应该作好充分准备,以端正的态度来对待,耐心的解决其中的难点,自己实在解决不了的地方应该及时虚心的向老师或其他同学请教,然后及时总结经验和教训。同时还让我明白了小组间团结与合作的重要。通过我们的共同努力,我们终于完成了这次实训。不敢说做的好,但我们确实尽力了。有了这次实训的经验,相信我会在以后的学习中更加努力的。(2) 通过C语言的实训,让我对C语言程序的用途有了更加广泛的了解。从本次实训中,我得到了很多的收获,浮点类型的变量不可以直接读取,必须要经过一个中间变量;在此之前,我对数组的学习不够深入,通过这一段时间的实训,让我加深了对数组这一部分的学习,使自己更加明白数组该如何更好的运用;以前对函数的运用不太熟练,现在使自己清晰了函数的定义,明白如何调用函数。在编写程序的过程中,我也遇到了很多困难,自己在编写程序的时候难免会因为自己的一些知识欠缺,使自己编写的程序出现错误,在这样的时候,我就会自己看看教材,或者问问同学,尽量自己将遇到的困难解决,如若实在不会的,就会请我们组的田莉帮我检查问题的所在,并且将不懂的地方弄懂;也会出现在