1、 - 课程设计报告 课程名称: C语言程序设计课设 工程名称:饭卡管理系统 学 院:专 业: 姓 名: 学号: 指导教师:成 绩: .
2、 . word.zl- .. - 目 录 第1局部课程设计题目与要求2 1.问题描述2 2.功能要求2 3.任务分工2 第2局部?饭卡管理系统?的设计与功能实现3 1.总体设计3 2.数据构造3 3.算法设计4 4.程序代码设计12 5.测试与调试22 第3局部
3、课程设计总结24 个人总结24 个人总结26 完毕语27 附录Ⅰ程序清单28 附录Ⅱ用户使用说明书39 参考文献39 . . word.zl- .. - 第1局部 课程设
4、计题目与要求 1. 问题描述 请输入选项编号〔0~7〕: 1— 建立饭卡文件 2— 买饭 3— 续钱 4— 添加新饭卡 5— 注销旧饭卡 6— 设置与解除挂失 7— 创新功能 0—退出系统 学校等大单位集体食堂买饭时间非常集中,这时如果食堂使用饭票卖饭,大家就得排长队等候,而且还要经过先去买饭票等麻烦的经历。因此食堂提出使用计算机进展管理,食堂用饭卡卖饭,不仅提高卖饭速度,还易于管理,减少不必要的麻烦,同时减轻管理人员的工作负担。 2. 功能要求 重复显示如下图的主菜单,在主菜单中选择任意一项,均实现相应功能。 在主菜单中选择1,建立名为card.dat的文
5、件,并在其中添加假设干人的饭卡号、、金额、挂失信息,要求饭卡号是唯一的。 在主菜单中选择2,要求用户输入饭卡号、饭费,然后系统自动从该人的饭卡中减去饭钱,并分别显示买饭前后的金额,如果原来饭卡中的金额缺乏5元,那么不能买饭,而且显示“金额缺乏够,请续钱!〞,如果挂失信息为真,那么显示“本卡已冻结!〞。 在主菜单中选择4,添加新饭卡,这时要求新饭卡号和已有的饭卡号不能重号。 在主菜单中选择5,注销旧饭卡。 在主菜单中选择6,要求用户输入饭卡号和挂失信息,然后更新该饭卡的挂失信息。 在主菜单中选择7, 在主菜单中选择0,显示“感使用本软件!已正常退出,按任意键完毕。〞按任意
6、键退出本系统。 第2局部 ?饭卡管理系统?的设计与功能实现 1.总体设计 图1初始的主模块 图2细分后的主模块图 2.数据构造 例如: struct card { char name[10],num[10]; float yu,sum; int guashi; }; num[10]表示学号放在一维数组中,name[10]表示放在一维数组中,yu表示余额,sum表示消费金额的累积,guashi表示挂失的情况。 3. 算法设计 图3主函数流程图 .
7、 . word.zl- .. - 图4 建立饭卡模块流程图 图5 买饭模块流程图 图6 续钱模块流程图 图7 添加新饭卡模块流程图 图8 注销旧饭卡模块流程图 图9 设置与解除挂失模块流程图 图10 创新功能模块流程图 4.程序
8、代码设计 采用模块化的思想,按照“自顶向下,逐步细化〞的原那么设计算法。 (1) 菜单的设计 1, 本例需要输出主菜单项选择择界面,简单菜单的制作可利用printf函数实现。用printf函数将菜单项逐一打印到屏幕上,界面中的边框可以通过多个printf函数输出的“|〞和“-〞拼接起来。 2, 菜单应根据用户的选择做出不同的反响,因此需要使用分支构造实现选择选项的功能。根据题意,主菜单含有8个菜单项选择项,属于多分支条件判断,使用带break和switch语句最为适宜。 3, 因为本例具有重复选择主菜单项选择项的功能,因此需要使用循环构造。在本例中菜单至少要显示一次,随后才判断是否继
9、续选择主菜单,所以使用do-while循坏比拟好,因为do-while循坏是先执行循环体,然后再判断表达式。 4,作为菜单,应该给用户一个正常的出口,即满足一定条件时退出程序。为了给用户提供方便,我们采用人机对话形式,当用户选择某一菜单项后,系统立即完成相应的功能,然后询问用户是否需要继续选择,只要用户继续选择〔输入y或Y〕,主菜单就会在屏幕上反复出现,只有当用户不再选择〔输入N或n〕,才可退出主菜单。除此之外,为了使用方便,在主菜单中还特设0选项,选择它也能正常退出程序。为了实现上述功能,有关语句都应放在do-while循环体中。 选择选项的程序段可设计成如下形式: choose=ge
10、tchar(); switch(choose) { case '1':mycreat();break; case '2':mybuy();break; case '3':myaddyu();break; case '4':myaddcard();break; case '5':myzhuxiao();break; case '6':mysetguashi();break; case '7':mynew();break; case '0':{printf("\n 非常感使用本软件!\n 已正常退出,按任意键完毕....");exit(0);}break;
11、 default :{printf("\n 该选项非法!");}break; } ( 2 ) 设计各模块的算法,这是逐步细化的过程。 1,建立饭卡模块,函数名 mycreat。 在该模块中输入学生的卡号,,充值钱数,并将它们存放在文件中;每输入一组数据,记录数增1。 建立饭卡的程序设计如下: void mycreat() { int i=1; struct card temp={0}; FILE *fp=NULL; char yes_no='\0'; temp.guashi=0; temp.sum=0; system("cls");
12、fp=fopen("D:\\饭卡管理系统\\files\\card.dat","a"); if(fp==NULL) {printf("\n\n 饭卡文件丧失!按任意键继续...");getchar();exit(0);} else { fclose(fp); do { printf("\n 请输入第%d个记录:\n\n",i); printf(" 卡号:");scanf("%s",&temp.num); if(myexist(temp.num)!=1) { fp=fopen("D:\\饭卡管理系统\\fil
13、es\\card.dat","a"); printf(" :"); scanf("%s",&temp.name); printf(" 充值钱数:"); scanf("%f",&temp.yu); fprintf(fp,"%10s%10s%20.2f%4d%20.2f\n",temp.num,temp.name,temp.yu,temp.guashi,temp.sum); fclose(fp); i++; } else printf(" 卡号重复!\n"); printf("\n 请问您要
14、继续吗?"); do { yes_no=getchar(); }while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n'); }while(yes_no=='Y'||yes_no=='y'); } } 在文件夹中寻找已输入的卡号用函数 myexist 系统自动用循环将文件中读入的学 号一一做比拟。 用fp=fopen("D:\\饭卡管理系统\\files\\card.dat","a");追加翻开文件,输入学生的,充值钱数,并将它们存放在文件中;每输入一组数据,记录数增1。 用
15、do---while语句实现人机对话的功能,机器问用户是否继续,如果继续就接着建立新饭卡,否那么返回主菜单。 2,买饭设计模块,函数名mybuy. void mybuy() system("cls"); fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r"); while(feof(fp)==0) { fscanf(fp,"%s%s%f%d%f",temp[i].num,temp[i].name,&temp[i].yu,&temp[i].guashi,&temp[i].sum); i++; } fclose(fp);
16、printf("\n 请输入卡号:");scanf("%s",num_temp); if(myexist(num_temp)==-1) printf("\n 卡号不存在!"); else if(myguashi(num_temp)==1) printf("\n 本卡已冻结!"); else if(myyu(num_temp)==0) printf("\n 余额不够,请续费!"); else { for(j=0;j
17、"%f",&money); printf("\n 卡号余额\n"); printf("\n 消费前: %-10s %-10s %-10.2f\n",temp[j].num,temp[j].name,temp[j].yu); printf("\n 消费后: %-10s %-10s %-10.2f\n",temp[j].num,temp[j].name,temp[j].yu-money); temp[j].yu=temp[j].yu-money; temp[j].sum=temp[j].sum+money; fp=f
18、open("D:\\饭卡管理系统\\files\\card.dat","w");
for(j=0;j 19、数名myexist。系统自动用循环将文件中读入的学号一一做比拟。
判断卡号挂失情况模块:函数名myguashi。系统自动用if---else语句判断挂失情况。
判断卡号余额情况模块:函数名myyu。系统自动用if---else语句分别判断卡号余额是否充足。
3,续钱设计模块,函数名myaddyu。
void myaddyu()
system("cls");
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r");
while(feof(fp)==0)
{ fscanf(fp,"%s%s%f%d%f\n",temp[i].num,tem 20、p[i].name,&temp[i].yu,&temp[i].guashi,&temp[i].sum);
i++;
}
fclose(fp);
printf("\n\n 请输入卡号:");scanf("%s",&num_temp);
if(myexist(num_temp)==1&&myguashi(num_temp)==0)
{ for(j=0;j 21、号余额\n");
printf(" 续费前:%-10s %-10s %-10.2f\n\n",temp[j].num,temp[j].name,temp[j].yu);
printf(" 续费后:%-10s %-10s %-10.2f\n",temp[j].num,temp[j].name,temp[j].yu+money);
temp[j].yu=temp[j].yu+money;
}
}
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","w");
for(k=0;k 22、intf(fp,"%10s%10s%20.2f%4d%20.2f\n",temp[k].num,temp[k].name,temp[k].yu,temp[k].guashi,temp[k].sum);
fclose(fp);
printf("\n\n 续费成功!按任意键返回主菜单......");
}
else
printf("\n\n 卡号不存在或已挂失!按任意键返回主菜单...");
getchar();
判断卡号存在情况:函数名myexist。系统自动用循环将文件中读入的学号一一做比拟。
判断挂失情况:函数名myguashi。系统自动用if---else语句 23、判断挂失情况。
用for循环构造找寻对应的学号,并输入续费金额,使续费成功。
备注:以下函数为续钱设计模块的子函数:
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r");
while(feof(fp)==0)
{ fscanf(fp,"%s%s%f%d%f\n",temp[k].num,temp[k].name,&temp[k].yu,&temp[k].guashi,&temp[k].sum);
k++;
}
fclose(fp);
for(i=0;i 24、)==0)
{ flag=1;
break;
}
}
return flag;
}
4,添加新饭卡模块,函数名myaddcard。
在该模块中输入学生的卡号,,充值钱数,并将它们存放在文件中;每输入一组数据,记录数增1。
添加饭卡模块设计程序如下:
void myaddcard
{ int i=0;
struct card temp={0};
FILE *fp=NULL;
char yes_no='\0';
temp.guashi=0;
temp.sum=0;
system("cls");
fp=fopen("D:\\饭卡管 25、理系统\\files\\card.dat","r");
if(fp==NULL) {printf("\n 饭卡文件丧失!");getch();exit(0);}
fclose(fp);
do
{ printf("\n 请输入第%d个记录:\n\n",i+1);
printf(" 卡号:");scanf("%s",&temp.num);
if(myexist(temp.num)!=1)
{ printf(" :");
scanf("%s",&temp.name);
printf(" 充值钱数:");
scanf("%f",&temp.yu);
fp= 26、fopen("D:\\饭卡管理系统\\files\\card.dat","a");
fprintf(fp,"%10s%10s%20.2f%4d%20.2f\n",temp.num,temp.name,temp.yu,temp.guashi,temp.sum);
fclose(fp);
i++;
}else printf("\n 卡号重复!\n");
printf("\n\n 要继续吗?");
do{yes_no=getch();
}while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');
}while( 27、yes_no=='Y'||yes_no=='y');
在文件夹中寻找已输入的卡号用函数 myexist 系统自动用循环将文件中读入的学
号一一做比拟。
没有找到,符合条件并输入学生的,充值钱数,并将它们存放在文件中;
每输入一组数据,记录数增1。
5,注销旧饭卡模块,函数名myzhuxiao。
system("cls");
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r");
if(fp==NULL) {printf("\n 饭卡文件丧失!");exit(0);}
while(feof(fp)==0)
{ fscanf(fp 28、"%s%s%f%d%f\n",temp[i].num,temp[i].name,&temp[i].yu,&temp[i].guashi,&temp[i].sum);
i++;
}
fclose(fp);
printf("\n\n 请输入卡号:");scanf("%s",num_temp);
if(myexist(num_temp)==1)
{ for(j=0;j 29、open("D:\\饭卡管理系统\\files\\card.dat","w");
for(k=0;k 30、用比拟函数 strcmp(num_temp,temp[j].num)==0。
用for循环语句利用数组的替换使学生饭卡被注销。
6,设置与解除挂失模块,函数名mysetguashi。
system("cls");
printf("\n");
printf(" |******************************************|\n");
printf(" | 请输入选项编号(0~2) |\n");
printf(" |******************************************|\n" 31、);
printf(" | 1--设置挂失 |\n");
printf(" | |\n");
printf(" | 2--解除挂失 |\n");
printf(" | |\n");
printf(" | 0--返回 |\n");
printf(" |* 32、\n");
printf("\n 请输入操作编号");
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r");
if(fp==NULL) {printf("\n 饭卡文件丧失!");exit(0);}
while(feof(fp)==0)
{ fscanf(fp,"%s%s%f%d%f\n",temp[i].num,temp[i].name,&temp[i].yu,&temp[i].guashi,&temp[i].sum);
i++;
}
fcl 33、ose(fp);
choose=getchar();
if(choose=='1')
{ printf("\n\n 请输入卡号:");scanf("%s",&num_temp);
if(myexist(num_temp)==1)
{ for(j=0;j 34、20.2f%4d%20.2f\n",temp[k].num,temp[k].name,temp[k].yu,temp[k].guashi,temp[k].sum);
fclose(fp);
printf("\n 设置成功!按任意键返回主菜单......");getch();return;
}else {printf("\n 此卡不存在!按任意键返回主菜单......");getch();return;}
}
else if(choose=='2')
{ printf("\n\n 请输入卡号:");scanf("%s",&num_temp);printf("\n");
35、
if(myexist(num_temp)==1)
{ for(j=0;j 36、
}else {printf(" 此卡不存在!按任意键返回主菜单......");getch();}
}
用if---else语句分别选择设置和解除挂失功能。
备注:以下函数为设置与解除挂失的子函数:
int myguashi(char num[10])
{ FILE *fp=NULL;
struct card temp[N]={0};
int i=0,j;
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r");
while(feof(fp)==0)
{ fscanf(fp,"%s%s%f%d%f\n",temp[i] 37、num,temp[i].name,&temp[i].yu,&temp[i].guashi,&temp[i].sum);
i++;
}
fclose(fp);
for(j=0;j 38、fp==NULL) {printf("\n 翻开文件失败!\n");return;}
while(feof(fp)==0)
{
fscanf(fp,"%s%s%f%d%f\n",temp[k].num,temp[k].name,&temp[k].yu,&temp[k].guashi,&temp[k].sum);
k++;
}
fclose(fp);
system("cls");
printf("请输入卡号:");
scanf("%s",num_temp);
for(i=0;i 39、p(num_temp,temp[i].num)==0) break;
if(temp[i].sum>=50)
{
temp[i].yu=temp[i].sum/50+temp[i].yu;
temp[i].sum=(int)temp[i].sum%50;
printf("余额为%f",temp[i].yu);
}
else printf("您的消费金额缺乏50");
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","w");
for(j=0;j 40、10s%20.2f%4d%20.2f%\n",temp[j].num,temp[j].name,temp[j].yu,temp[j].guashi,temp[j].sum);
fclose(fp);
printf("\n 请问您要继续吗?");
do
{
yes_no=getchar();
}while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');
}while(yes_no=='Y'||yes_no=='y');
}
用if---else语句判断消费金额是否大于50元。
如 41、果大于五十元用到temp[i].yu,temp[i].sum计算出返回金钱。
8,界面设计模块,函数名myprint。
void myprint()
{ system("cls");
printf("\n\n");
printf(" |******************************************|\n");
printf(" | 请输入选项编号(0~7) |\n");
printf(" |******************************************|\n");
printf( 42、" | 1--建立饭卡文件 |\n");
printf(" | 2--买饭 |\n");
printf(" | 3--续钱 |\n");
printf(" | 4--添加新饭卡 |\n");
printf(" | 5--注销旧饭卡 |\n");
printf(" | 6--设置与解除 43、挂失 |\n");
printf(" | 7--创新功能 |\n");
printf(" | 0--退出系统 |\n");
printf(" |******************************************|\n");
}
利用myprint函数实现主菜单的显示功能。
备注以下为查找学生饭卡卡号的子函数:
int myexist(char num[10])
{
FILE *fp=NULL;
s 44、truct card temp[N]={0};
int i=0,flag=-1,k=0;
fp=fopen("D:\\饭卡管理系统\\files\\card.dat","r");
while(feof(fp)==0)
{
fscanf(fp,"%s%s%f%d%f\n",temp[k].num,temp[k].name,&temp[k].yu,&temp[k].guashi,&temp[k].sum);
k++;
}
fclose(fp);
for(i=0;i 45、 flag=1;break; }
return flag;
}
5.测试与调试
测试数据类型
测试数据
预期结果
实例结果
合法数据
1
建立1-10个学生饭卡,1-5输入金额50元以下,6-10输入金额50以上。
查看档案,存在与刚刚对应的十条记录。
查看档案,存在与刚刚对应的十条记录。
2
对卡号1-10卡号中任选一个进展买饭,输入消费金额20元。
显示饭卡余额的信息,并且相应的扣除金额20元。
显示饭卡余额的信息,并且相应的扣除金额20元。
3
从1-10个卡号中任选一个进展续钱,续钱金额为100元。
该学号 46、对应的余额增加100元。
该学号对应的余额增加100元。
4
添加新饭卡,卡号为11,续费金额为200元。
查看档案,多了一个卡号为11的记录,且信息与对应的输入信息相等。
查看档案,多了一个卡号为11的记录,且信息与对应的输入信息相等。
5
改变卡号为5的档案,使其消费累计金额为200元,之后进展返值操作
该用户消费后的余额增加2元。
该用户消费后的余额增加2元。
6
输入用户须知对应的选项号。
屏幕上出现用户须知的容。
屏幕上出现用户须知的容。
7
选择卡号为6进展挂失操作,选择设置挂失
查看档案,卡号为6的用户饭卡已挂失。
查看档案,卡号为6的用户饭卡已 47、挂失。
8
把学号为11的用户进展注销操作。
查看档案,卡号为11的用户的相关记录消失。
查看档案,卡号为11的用户的相关记录消失。
9
选择卡号为6进展挂失操作,选择解除挂失
查看档案,卡号为6的用户饭卡已解除挂失。
查看档案,卡号为6的用户饭卡已解除挂失。
10
用户输入0
屏幕显示退出的相关提示信息,之后再按任何键时,能够退出。
屏幕显示退出的相关提示信息,之后再按任何键时,能够退出。
非法数据
1
对卡号为1的用户进展添加饭卡。
显示学号重复相关的错误信息。
显示学号重复相关的错误信息。。
2
对学号为2的用户进展买饭操作。
显示消费金额缺乏 48、相关的错误信息。
显示消费金额缺乏相关的错误信息。
3
对卡号为3的用户进展两次注销。
在第二次注销时,显示卡号不存在。
在第二次注销时,显示卡号不存在。
4
对卡号为1的用户进展饭卡建立操作。
显示卡号重复相关的错误信息。
显示卡号重复相关的错误信息。
5
对卡号为4的用户进展续钱操作
显示学号不存在相关信息。
显示学号不存在相关信息。
6
把卡号为5的用户进展返值的操作
显示消费金额缺乏的错误信息。
显示消费金额缺乏的错误信息。
7
用户在主界面输入任何0-7以外的信息
屏幕上显示‘选项非法’错误。
屏幕上显示‘选项非法’错误。
49、
. . word.zl-
.. -
. 50、 . word.zl-
.. -
附录Ⅰ 程序清单
#include






