c语言饭卡管理系统课程设计报告.docx
《c语言饭卡管理系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《c语言饭卡管理系统课程设计报告.docx(38页珍藏版)》请在冰豆网上搜索。
c语言饭卡管理系统课程设计报告
课程设计报告
课程名称:
C语言程序设计课设
项目名称:
饭卡管理系统
学院:
专业:
姓名:
学号:
***********
第1部分课程设计题目与要求
1.问题描述
请输入选项编号(0~7):
1—建立饭卡文件
2—买饭
3—续钱
4—添加新饭卡
5—注销旧饭卡
6—设置与解除挂失
7—创新功能
0—退出系统
学校等大单位集体食堂买饭时间非常集中,这时如果食堂使用饭票卖饭,大家就得排长队等候,而且还要经过先去买饭票等麻烦的经历。
因此食堂提出使用计算机进行管理,食堂用饭卡卖饭,不仅提高卖饭速度,还易于管理,减少不必要的麻烦,同时减轻管理人员的工作负担。
2.功能要求
重复显示如图所示的主菜单,在主菜单中选择任意一项,均实现相应功能。
在主菜单中选择1,建立名为card.dat的文件,并在其中添加若干人的饭卡号、姓名、金额、挂失信息,要求饭卡号是唯一的。
在主菜单中选择2,要求用户输入饭卡号、饭费,然后系统自动从该人的饭卡中减去饭钱,并分别显示买饭前后的金额,如果原来饭卡中的金额不足5元,则不能买饭,而且显示“金额不足够,请续钱!
”,如果挂失信息为真,则显示“本卡已冻结!
”。
在主菜单中选择4,添加新饭卡,这时要求新饭卡号和已有的饭卡号不能重号。
在主菜单中选择5,注销旧饭卡。
在主菜单中选择6,要求用户输入饭卡号和挂失信息,然后更新该饭卡的挂失信息。
在主菜单中选择7,
在主菜单中选择0,显示“感谢使用本软件!
已正常退出,按任意键结束。
”按任意键退出本系统。
第2部分《饭卡管理系统》的设计与功能实现
1.总体设计
图1初始的主模块
图2细分后的主模块图
2.数据结构
例如:
structcard
{charname[10],num[10];floatyu,sum;intguashi;
};num[10]表示学号放在一维数组中,name[10]表示姓名放在一维数组中,yu表示余额,sum表示消费金额的累积,guashi表示挂失的情况。
3.算法设计
图3主函数流程图
图4建立饭卡模块流程图
图5买饭模块流程图
图6续钱模块流程图
图7添加新饭卡模块流程图
图8注销旧饭卡模块流程图
图9设置与解除挂失模块流程图
图10创新功能模块流程图
4.程序代码设计
采用模块化的思想,按照“自顶向下,逐步细化”的原则设计算法。
(1)菜单的设计
1,本例需要输出主菜单选择界面,简单菜单的制作可利用printf函数实现。
用printf函数将菜单项逐一打印到屏幕上,界面中的边框可以通过多个printf函数输出的“|”和“-”拼接起来。
2,菜单应根据用户的选择做出不同的反应,因此需要使用分支结构实现选择选项的功能。
根据题意,主菜单含有8个菜单选项,属于多分支条件判断,使用带break和switch语句最为合适。
3,因为本例具有重复选择主菜单选项的功能,因此需要使用循环结构。
在本例中菜单至少要显示一次,随后才判断是否继续选择主菜单,所以使用do-while循坏比较好,因为do-while循坏是先执行循环体,然后再判断表达式。
4,作为菜单,应该给用户一个正常的出口,即满足一定条件时退出程序。
为了给用户提供方便,我们采用人机对话形式,当用户选择某一菜单项后,系统立即完成相应的功能,然后询问用户是否需要继续选择,只要用户继续选择(输入y或Y),主菜单就会在屏幕上反复出现,只有当用户不再选择(输入N或n),才可退出主菜单。
除此之外,为了使用方便,在主菜单中还特设0选项,选择它也能正常退出程序。
为了实现上述功能,有关语句都应放在do-while循环体中。
选择选项的程序段可设计成如下形式:
choose=getchar();
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;
default:
{printf("\n该选项非法!
");}break;
}
(2)设计各模块的算法,这是逐步细化的过程。
1,建立饭卡模块,函数名mycreat。
在该模块中输入学生的卡号,姓名,充值钱数,并将它们存放在文件中;每输入一组数据,记录数增1。
建立饭卡的程序设计如下:
voidmycreat()
{
inti=1;
structcardtemp={0};
FILE*fp=NULL;
charyes_no='\0';
temp.guashi=0;
temp.sum=0;
system("cls");
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:
\\饭卡管理系统\\files\\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++;
}
elseprintf("卡号重复!
\n");
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');
}
}
在文件夹中寻找已输入的卡号用函数myexist系统自动用循环将文件中读入的学
号一一做比较。
用fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","a");追加打开文件,输入学生的姓名,充值钱数,并将它们存放在文件中;每输入一组数据,记录数增1。
用do---while语句实现人机对话的功能,机器问用户是否继续,如果继续就接着建立新饭卡,否则返回主菜单。
2,买饭设计模块,函数名mybuy.
voidmybuy()
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);
printf("\n请输入卡号:
");scanf("%s",num_temp);
if(myexist(num_temp)==-1)printf("\n卡号不存在!
");
elseif(myguashi(num_temp)==1)printf("\n本卡已冻结!
");
elseif(myyu(num_temp)==0)printf("\n余额不够,请续费!
");
else
{for(j=0;j
if(strcmp(num_temp,temp[j].num)==0)break;
printf("\n请输入消费金额:
");scanf("%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=fopen("D:
\\饭卡管理系统\\files\\card.dat","w");
for(j=0;jfprintf(fp,"%10s%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\n此次消费成功!
按任意键返回主菜单.....");getch();return;
}
printf("\n\n此次消费失败!
按任意键返回主菜单...");getch();
判断卡号存在模块:
函数名myexist。
系统自动用循环将文件中读入的学号一一做比较。
判断卡号挂失情况模块:
函数名myguashi。
系统自动用if---else语句判断挂失情况。
判断卡号余额情况模块:
函数名myyu。
系统自动用if---else语句分别判断卡号余额是否充足。
3,续钱设计模块,函数名myaddyu。
voidmyaddyu()
system("cls");
fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","r");
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++;
}
fclose(fp);
printf("\n\n请输入卡号:
");scanf("%s",&num_temp);
if(myexist(num_temp)==1&&myguashi(num_temp)==0)
{for(j=0;j
{if(strcmp(num_temp,temp[j].num)==0)
{printf("\n请输入续费金额:
");scanf("%f",&money);
printf("\n卡号姓名余额\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
fprintf(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语句判断挂失情况。
用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{if(strcmp(num,temp[i].num)==0)
{flag=1;
break;
}
}
returnflag;
}
4,添加新饭卡模块,函数名myaddcard。
在该模块中输入学生的卡号,姓名,充值钱数,并将它们存放在文件中;每输入一组数据,记录数增1。
添加饭卡模块设计程序如下:
voidmyaddcard
{inti=0;
structcardtemp={0};
FILE*fp=NULL;
charyes_no='\0';
temp.guashi=0;
temp.sum=0;
system("cls");
fp=fopen("D:
\\饭卡管理系统\\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=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++;
}elseprintf("\n卡号重复!
\n");
printf("\n\n要继续吗?
");
do{yes_no=getch();
}while(yes_no!
='Y'&&yes_no!
='y'&&yes_no!
='N'&&yes_no!
='n');
}while(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,"%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
if(strcmp(num_temp,temp[j].num)==0)
break;
for(k=j;k
temp[k]=temp[k+1];
fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","w");
for(k=0;kfprintf(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注销成功!
按任意键返回主菜单......");
}
else
printf("\n%s不存在!
按任意键返回主菜单......",num_temp);
getch();
查找学生饭卡卡号用比较函数strcmp(num_temp,temp[j].num)==0。
用for循环语句利用数组的替换使学生饭卡被注销。
6,设置与解除挂失模块,函数名mysetguashi。
system("cls");
printf("\n");
printf("|******************************************|\n");
printf("|请输入选项编号(0~2)|\n");
printf("|******************************************|\n");
printf("|1--设置挂失|\n");
printf("||\n");
printf("|2--解除挂失|\n");
printf("||\n");
printf("|0--返回|\n");
printf("|******************************************|\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++;
}
fclose(fp);
choose=getchar();
if(choose=='1')
{printf("\n\n请输入卡号:
");scanf("%s",&num_temp);
if(myexist(num_temp)==1)
{for(j=0;j
if(strcmp(num_temp,temp[j].num)==0)break;
temp[j].guashi=1;
fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","w");
for(k=0;k
fprintf(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设置成功!
按任意键返回主菜单......");getch();return;
}else{printf("\n此卡不存在!
按任意键返回主菜单......");getch();return;}
}
elseif(choose=='2')
{printf("\n\n请输入卡号:
");scanf("%s",&num_temp);printf("\n");
if(myexist(num_temp)==1)
{for(j=0;j
if(strcmp(num_temp,temp[j].num)==0)break;
temp[j].guashi=0;
fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","w");
for(k=0;k
fprintf(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);
}else{printf("此卡不存在!
按任意键返回主菜单......");getch();}
}
用if---else语句分别选择设置和解除挂失功能。
备注:
以下函数为设置与解除挂失的子函数:
intmyguashi(charnum[10])
{FILE*fp=NULL;
structcardtemp[N]={0};
inti=0,j;
fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","r");
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++;
}
fclose(fp);
for(j=0;j
{if(strcmp(num,temp[j].num)==0)
break;
}
if(temp[j].guashi==1)
return1;
else
return0;
}
7,创新功能模块,函数名mynew。
do
{
fp=fopen("D:
\\饭卡管理系统\\files\\card.dat","r");
if(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);