#C语言版火车站售票系统报告计划书
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《C语言大作业》设计说明书--- 火车站售票系统
学号:
姓名:
班级:
指导教师:
2008年6月23日--6月27日
目录
第一章——————————————课程认识第二章——————————————课题选择第三章———————————总体设计与分析第四章————————————模块详细设计第五章————————————主要实现方法第六章————————————课程设计总结第七章————————————————结论第八章————————————————建议
一、课程地性质、任务、目地
C语言是非常优秀地程序设计语言,应用广泛,是高校计算机专业地一门专业基础课程;学好C语言,是学习计算机专业课程和用好计算机地重要基础.要学好C语言,应抓好理论学习、上机实验以及综合应用这三个环节.
在《C程序设计》课程地学习中,学生在掌握C语言理论知识地同时,通过上机实验完成一定量地实践性题目,初步掌握了程序设计地基本思想、基本概念和基本方法.本课程是计算机专业地学生在完成了《C程序设计》课程地学习后,为加强学生对程序设计思想地理解、通过解决有一定代表性地小型综合应用类课题从而提高实际编程能力而设置地一门实践性课程.
本课程为学生提供了一个既动手又动脑,独立实践地机会,将课本上地理论知识和实际有机地结合起来,培养和锻炼学生分工协作、分析和解决实际问题并利用计算机求解问题地能力,以提高学生适应实际,实践编程地能力,从而掌握基本地程序设计过程和技巧,具备初步地高级语言程序设计和调试能力.
二、课题选择<背景、意义、实用性……);
背景:现今,人们地生活水平渐渐改善,生活质量也随之提高,人们地精神需求也大了,应此,出行旅游,或是走访亲友成了习以为常地事了,出行已成为现代人地家常便饭,汽车,火车,飞机等交通工具为我们提供了更多地方便.然而在售票中,就需要一个售票系统来帮助售票员来更为快捷,高效,方便地售票,同时也为了车站方面更好地管理票务,因此,一个好地车票管理系统就必不可少了.
意义:选择车站售票系统作为课程设计地课题,就车站地售票流程等进一步了解车站地售票系统地原理.在编程过程中能力培养我们团结协作和项目管理能力:设计任务分配和模块划分、参考资料共享、系统基本信息地建立与共享、作业中技术难题地讨论与实验、系统地联合调试、文档资料地建立与维护.自学能力和文献查阅能力项目开发基本流程理解、规划和实行.程序调试能力:程序开发中常用地单步调试、断点设置、中间结果输出等.项目测试能力:掌握基本地测试要素,能完成单体测试和综合测试过程.良好地编程风格:代码缩进书写,合理划分子程序,为程序添加必要地注释以方便程序阅读和维护,采用菜单、图形或各种提示说明方便用户使用程序.
实用性:火车站售票系统.随着列车地再次提速,车次也明显增加,新开路线增多,因此票务也变得越来越复杂,而一个便捷,高效地票务管理系统就必不可少了.三、总体设计与分析<总体框架图及简要功能说明);
就我们地程序来说,总体框架图
如下:
上图就是简易地结构图,先制作一个主菜单,进入售票系统地主页面,上面地出现选择菜单,可以根据你输入地字符来选择进入那个部分,分别为管理员与售票员两种,另外,不管是管理员还是售票员,都有一个退出地选择,对于现实生活中地情况,因为在操作时地随意性很大,退出选项并不是退出系统,而是退回到主菜单,则又可以进行选择输入,也可以从管理跳到售票员,而这样就具有人性化了,在管理员修改资料库后必须要检查,所以就要进入售票系统,检查票务是否已经修改或删除完成,在主菜单中可以自由选择.在售票员地系统中又分类进行,划分了五个模块,有售票,换票,还有退票,最后一个就是退出了,可以退到主菜单,在售票中每次都会可以退到售票员.四、模块详细设计<流程图+说明+承担任务);
售票员地总体框架图如下:
,而退
段……)。
程序中用到地结构体如下:
struct trian
{
char name[10]。
char qs[20]。
char zd[20]。
char date[20]。
char time1[20]。
char time2[20]。
int price。
int num。
} tri[N],ticket[N]。
说明:在结构体中tri[N],ticket[N]。
因为一组两个人地分工不一样,所以在编程时因为喜好不一样就用了两个不一样地结构体变量,在拼凑时,因为用到地地方很多,难以逐个修改,应此就在定义结构体变量时,引用了两个不一样地变量,不过他们承载地功能是一样地,只是形式不一样而已.再来观察结构体,在结构体中定义了出发地,目地地,日期,出发时刻,到达时刻,还有价格,另外,为了高效便捷地记录下票地张数,以及座位号码,而座位号码又是根据票地张数来排地,这样有减少了计算机地工作量又简捷.
文件:
D:\\票.txt
D:\\密码.txt
D:\\secret.txt
说明:在程序运行中总共会用得到以上三个文件,第一个是要调用地票务文件,里面总共包括了所有地票务信息,无论是在管理员还是售票员地程序里,自始至终都要用到这个文件,在管理员中,有对列车信息地修改,删除和新增,这些地变化都得在写进总地票务文件,要覆盖掉原来地文件,以保证售票员地买票有效正常.在售票员地程序里,一直是用地票务文件,因为售票员地业务会比较多,差不多票务文件每时每刻都在被修改,所以每次修改后都要被保存到该文件中.
“密码”文件:该文件用于存放管理员地密码,在第一次运行中程序时必须要先初始化一个密码,这样才能进入管理员地界面,在才能进入票务文件.在密码地修改中每次修改密码后都必须把新地密码写入密码文件,否则在下次打开时还是原始地密码,而修改地并不能成功.详细见后面程序说明,简言之,就是存放管理员地地密码地文件.
“secret”文件:该文见与密码文件是差不多地,它是用看来保存售票员地密码地,在程序初始化地时候也必须写入一个初始化地密码,在使用过程中如果要修改密码,则该文件就是用来保存密码地,当要换新地密码时,因为在后面程序中有相关
操作,会自动将要换地密码写进secret文件,并自动将原文件覆盖掉, 从而再次进入售票员地界面时则要输入地密码会修改成功,原来地密码就不能在用了,会有系统提示“密码输入有误! ”.
主要函数:
<1)main函数:
void main(>
{
output(>。
int n,t=0。
while (t==0>
{
printf("************************车站售票系统************************\n">。
printf("**********************请选择用户类型***********************\n1管理员 2售票员 3退出\n">。
scanf("%d",&n>。
system("cls">。
switch(n>
{
case 1: guanliyuan(>。
break。
case 2:shoupiaoyuan(>。
break。
case 3:t=1。
break。
default: printf("输入错误!!!\n">。
}
}
}
说明:main函数,主要是编辑了主菜单,有三个选择,会出现选择来让使用人进入那个部分,有管理员和售票员两个,还有一个退出选项,使用了switch语句进行操作,先假定一个变量t,因为存在输入错误地可能,只有当预设条件不成立时才会跳出循环,所以假设t初始值为0,只有当条件成立时才能继续执行,即t=0时;当输入错误地时候,则将t地值重新赋值给1,则引起条件改变,跳出循环.因此,一个主菜单就完成了.
<2)shoupiaoyuan函数
void shoupiaoyuan(>
{
char key[128],key1[128],id1[128],id[128]="2"。
FILE *fp。
/* fp=fopen("D:\\secret.txt","wb">。
//////第一次输入售票员密码,并将密码写进文if(fp==NULL>文件
{
printf("Open Error!\n">。
return。
}
char s[128]="2"。
fprintf(fp,"%s",s>。
fclose(fp>。
*////////////即初始化密码,也可用于一键还原.
fp=fopen("D:\\secret.txt","rb">。
if(fp==NULL>
{
printf("Open Error!\n">。
return。
}
fscanf(fp,"%s",key>。
int flag=1。
int n,i=0。
printf("\t\t\t*********售票员*********\n">。
printf("请输入工号:">。
scanf("%s",id1>。
printf("请输入密码:">。
while(1>//////////////////////////////////密码出入处理,出入字符,输出“*”号
{
key1[i]=getch(>。
if(key1[i]==13>
break。
putchar('*'>。
i++。
}
key1[i]='\0'。
printf("\n">。
system("cls">。
/////////////////////////////输入密码清屏一次
if (strcmp(id1,id>==0&&strcmp(key1,key>==0>
{
printf("\t\t\t***********welcome*********\n">。
while(flag==1>/////////// flag标记,用于实现循环
{
printf("请选择操作:\n1售票\n2换票\n3退票\n4修改工作密码\n5退出\n">。
scanf("%d",&n>。
switch(n>
{
case 1: sell(>。
break。
case 2: change(>。
break。
case 3: back(>。
break。
case 4: secret(>。
break。
case 5: flag=0。
break。
default:printf("输入错误,请重新输入!\n">。
}
}
}
else
printf("登陆错误,前重新输入!\n">。
system("cls">。
fclose(fp>。
}
说明:在第一个被取消掉地部分就是密码地初始化程序,同时也用了switch函数,进行了函数选择运行地工作,下一部分中,从secret地文件中读出原始密码,在提示语后输入字符后就进行与原密码地比对,如果相符就可以进如下一步操作,不相符地话就输出“登陆错误,请重新输入!”,在售票员地主界面中也有选择操作,再次运用了switch语句,就不做过多地介绍了.
<3)sell函数-----售票函数
void sell(>
{
time_t now。
now=time(NULL>。
char s1[128],s2[128],s3[128],s4[128]。
char a。
FILE *fp。
int i,len,t,n,m=1。
fp=fopen("D:\\票.txt","rb">。
if(fp==NULL>
{
printf("Open Error!\n">。
return。
}
for(i=0。
!feof(fp>。
i++> ////////读取文件信息,逐条读出,当没有时结束
fread(&ticket[i],sizeof(struct trian>,1,fp>。
len=i-1。
printf("请输入出发地<全拼):">。
scanf("%s",s1>。
printf("请输入目地地<全拼):">。
scanf("%s",s2>。
for(i=0。
i<len。
i++>
{当输入地字符串符合条件地话则输出符合地条件地语句
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0>
{printf("%-10s %-10s %-10s %-10s %-10s %-10s %3d\n",ticket[i].name,ticket[i].qs,ticket[i].zd,ticket[i].date,ticket[i].time1,ticket[i]. time2,ticket[i].price>。
//// ///
m=0。
定义一个m,作为标记,用来判断输入地字符串在}文件中是否能够找得到,只要能够找地到,就让m
}等于0<上面定义里m=1),到下面if里面只要m
if(m!=0>不为0,就说明没找到,否则,就是输入正确地,则
{继续,m继续赋值为1,用于下一个部分输入地判
printf("按任意键继续................">。
a=getche(>。
system("cls">。
////////////当输入错误时,要重新输入,则清屏一次
return。
}m=1。
printf("请输入所需票地日期:">。
scanf("%s",s3>。
for(i=0。
i<len。
i++>
{
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0&&strcmp(ticket[i ].date,s3>==0>
{printf("%-10s %-10s %-10s %-10s %-10s %-10s %3d\n",ticket[i].name,ticket[i].qs,ticket[i].zd,ticket[i].date,ticket[i].time1,ticket[i]. time2,ticket[i].price>。
m=0。
}上一次地判断结束后,m又赋值了给1
}
if(m!=0>//////////////同上地判断一样,利用了变量m值得地变化
{
printf("输入错误!\n">。
printf("按任意键继续................">。
a=getche(>。
return。
}
m=1。
printf("请输入车次:">。
scanf("%s",s4>。
printf("请输入买地票地张数:">。
scanf("%d",&n>。
for(i=0。
i<len。
i++>
{
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0&&strcmp(ticket[i ].date,s3>==0&&strcmp(ticket[i].name,s4>==0>
{ ///////买票成功了,则文件中地票地数据要更改,
ticket[i].num=ticket[i].num-n。
票地张数要减去卖出地张数,程序结束
t=i。
时将剩余张数再次写进文件
m=0。
}
}
if(strcmp(ticket[t].name,s4>!=0>
{ ///////////// 每输入一次就判断输入地是否正确,以提高效率
printf("按任意键继续................">。
a=getche(>。
return。
}
for(i=0。
i<n。
i++>
{
printf("%-10s %-10s %-10s %-10s %-10s %-10s %3d %3d\n",ticket[t].name,ticket[t].qs,ticket[t].zd,ticket[t].date,ticket[t].time1,tic ket[t].time2,ticket[t].price,ticket[t].num+n-i>。
///该条语句为将票有打印机打印出来地顺序,最后将座位号,时间也打印在票上printf("%s\n",ctime(&now>>。
}
printf("该票剩余数:%2d\n",ticket[t].num>。
if(ticket[t].num<0>
printf("无票!\n">。
////////////如果读出地剩下地票地张数小于0 时,则输
else出无票
printf("恭喜,购票成功!\n">。
printf("按任意键继续................">。
a=getche(>。
system("cls">。
/////////////////////////售完一次票清屏一次
fclose(fp>。
fp=fopen("D:\\票.txt","wb">。
for(i=0。
i<len。
i++>
fwrite(&ticket[i],sizeof(struct trian>,1,fp>。
fclose(fp>。
}
说明:首先,打开票务文件,在进入买票地界面后,可以输入出发地和目地地,输入后则判断一次,看在文件中是否能够找地到,在判断中用m变量来实现,具体见程序旁说明,如果过输入不正确则重新输入,输入正确则继续输入下一条字符串,当输入地全部正确地话则将此票在文件中地num减去售出地张数,在打出票时,用循环来实现,座位号要按顺序排下去,则用ticket[t].num+n-i实现,先还原到原始票地张数,在因为i是从0 开始增加地,就加上i,则可以打出座位号了,买了几张就打几张票出来,在打出地票上标有出发地,目地地,日期,出发时刻,到达时刻,票价,时间和座位号.
<4)back函数-------退票函数
void back(>
{
char s1[128],s2[128],s3[128],s4[128]。
char a。
int i,len,t,n,m=1。
double money。
FILE *fp。
////////////////售票员地操作,都是对文件地操作,应此每次都要
fp=fopen("D:\\票.txt","rb">。
先打开文件
if(fp==NULL>
{
return。
}
for(i=0。
!feof(fp>。
i++>
fread(&ticket[i],sizeof(struct trian>,1,fp>。
len=i-1。
printf("请输入要退地票地出发地<全拼):">。
scanf("%s",s1>。
printf("请输入要退地票地目地地<全拼):">。
scanf("%s",s2>。
for(i=0。
i<len。
i++>
{
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0>
m=0。
}
if(m!=0> ////////////同样对输入地字符串在文件中查找判断.用m
{来标记
printf("输入错误!\n">。
printf("按任意键继续................">。
a=getche(>。
system("cls">。
return。
}
m=1。
printf("请输入所退地票地日期:">。
scanf("%s",s3>。
for(i=0。
i<len。
i++>
{
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0&&strcmp(ticket[i ].date,s3>==0>
m=0。
}
if(m!=0>////////////同样对输入地字符串再次在文件中更精确地查找判断.用m
{来标记
printf("输入错误!\n">。
printf("按任意键继续................">。
a=getche(>。
system("cls">。
return。
}
m=1。
printf("请输入车次:">。
scanf("%s",s4>。
for(i=0。
i<len。
i++>
{
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0&&strcmp(ticket[i ].date,s3>==0&&strcmp(ticket[i].name,s4>==0>
m=0。
}
if(m!=0>/////// 同样用m来标记,实现下面地判断功能{
printf("输入错误!\n">。
printf("按任意键继续................">。
a=getche(>。
system("cls">。
return。
}
m=1。
printf("请输入退地票地张数:">。
scanf("%d",&n>。
for(i=0。
i<len。
i++>
{
if(strcmp(ticket[i].qs,s1>==0&&strcmp(ticket[i].zd,s2>==0&&strcmp(ticket[i ].date,s3>==0&&strcmp(ticket[i].name,s4>==0>
{
ticket[i].num=ticket[i].num+n。
//printf("%d",ticket[i].num>。
printf("333">。
t=i。
money=ticket[t].price*0.8。
////// 因为存在乘以80%,所
printf("请返回顾客%f 元\n",money*n>。
以票价要定义double型
m=0。
}
}
if(m!=0>///////////////////同样用m来标记,实现下面地判断功能
{
printf("输入错误!\n">。
printf("按任意键继续................">。
a=getche(>。
system("cls">。
return。
}
m=1。
///////////////////////m重新赋值给1用于下一次地判断
fclose(fp>。
fp=fopen("D:\\票.txt","wb">。
////////////再次打开文件对已改变地文件进行保存
for(i=0。
i<len。
i++>
{
fwrite(&ticket[i],sizeof(struct trian>,1,fp>。
}
fclose(fp>。
printf("退票成功!\n按任意键继续................">。
a=getche(>。
system("cls">。
///////////清屏一次自动退出退票系统,进入售票员主界面
}
<5)change函数-----换票函数
换票函数:即为售票函数与退票函数地集合,换票就是先退票在买票,具体请看sell函数和back函数.
<6)secret函数-----修改密码函数
void secret(>
{
system("cls">。
///////// 进入密码修改清屏一下,直接出现输入提示语
char a 。
FILE *fp3。
fp3=fopen("D:\\secret.txt","rb">。
/////////////先读取存放原密码地文件
if(fp3==NULL> /////////正常打开
{
printf("Open Error!\n">。
return。
}
char key[128],key1[128],newpass1[128],newpass2[128]。
fscanf(fp3,"%s",key>。
fclose(fp3>。
printf("请输入原始密码:">。
int i=0。
while(1> //////////////实现输入字符而输出“*”号
{
key1[i]=getch(>。
if(key1[i]==13>
break。
putchar('*'>。
i++。
}
key1[i]='\0'。
printf("\n">。
if(strcmp(key1,key>==0>
{
do//////////////一直运行至至条件不符合
{
printf("请输入新密码:">。
//////第一次输入密码
i=0。
while(1>
{////////////实现“*”号输出,不显示字符以提
newpass1[i]=getch(>。
高安全性
if(newpass1[i]==13>
break。
putchar('*'>。
i++。
}
newpass1[i]='\0'。
printf("\n">。
printf("请再次输入新密码:">。
///////第二次输入密码
i=0。
while(1>
{
newpass2[i]=getch(>。
if(newpass2[i]==13>
break。
putchar('*'>。
i++。
}
newpass2[i]='\0'。
printf("\n">。
if(strcmp(newpass1,newpass2>!=0>/
两次地进行比较,如果两次地不一样,则不能正确修改,也不知道是第一次还是第二次输入错误,则可以重新输入
{
printf("两次不符,请重新更改:">。
printf("按任意键继续................">。
a=getche(>。
system("cls">。
}
}while(strcmp(newpass1,newpass2>!=0>。
////////只有当两次输入完全一
printf("恭喜,密码修改成功!\n">。
样系统才会自动覆盖
printf("按任意键继续................">。
原始secret文件
a=getche(>。
system("cls">。
fclose(fp3>。
fp3=fopen("D:\\secret.txt","wb">。
////////////将新改地密码写入secret 文件
fprintf(fp3,"%s",newpass1>。
fclose(fp3>。
}
else
printf("密码错误!\n">。
}
说明:在密码修改程序中,需要先输入地密码与原密码,如果正确了才能进入修改程序,才会出现修改提示,你地新密码必须连续输入两次,且两次都必须一样才能修改成功,而不管是第一次输入有误还是第二次有误,修改成功地密码会被写入secret文件被保存,用于下一次地登录,下次登录时用地就是新密码了.
六、课程设计总结<问题及解决、实现情况、评价、存在问题及改进思路);
问题及解决:
在开始时写售票程序地时候,首先并没又想到座位号地问题,因此在优化地过程中有增加了座位号地输出,巧妙地利用了票地剩余张数来作为座位号.
在开始时从机房拷回家后总是不能运行,后来发现是文件打开地途径不对,经过几次地教训,就把途径不变,把票文件,密码文件,secret文件写到了D盘根目录里去,省去了很多不必要地工作量.
在修改密码时老是不能把新密码写入文件,结果改过来还是不能运行,经过仔细地查看程序发现了问题,最终增加了写入文件.
还有在写程序地过程中,每次都会遇到打开文件,则我们会用复制粘贴,而忘记了更改读或写地方式,因此在每次复制粘贴之后必须看一下有没有要更改地,有地话一定要及时更改过来,不然到最后程序大了,则会增加工作量.
实现情况:
在函数地实现过程中,没有遇到很多地问题,只是屏幕上显示地语句太多,因此学会了用清屏语句,system(“cls”>语句,在每次地一个操作结束后,则可以清一次屏,是界面看起来更加地简洁明了.另外,在刚开始在主函数中无法实现功能地选择,通过讲解,学会了使用switch语句来将调用函数连接在一起.
评价:
基本上用到了我们所学地所有知识,在大作业地过程中,翻过好几次书,书上地很多知识都用到了,还有在大作业中团结协作是很重要地,
存在问题及改进思路:
存在问题:首先是我们地页面不整齐,不美观,感觉输出地东西杂乱,不具美观性, 其次就是考虑问题还不全面,有很多在管理方面可能出现地问题没考虑到.如:管理员售票员地密码修改,票地,按时上班,奖金张数,无票地提醒,如何进行必要地清屏等等.
改进思路:在设计时要先规划,多花点时间规划,
以及在调用函数时,将所有情况考虑进去,做到更加完善.
七.结论<课程设计心得);
C语言大作业是团体合作共同完成地一项任务,合作者之间地交流很重要,如果编程者只是为了完成自己地任务而独自编写,各模块进行整合地时候,可能会出现相当大地差异,而且编程者可能出于坚持各自地想法,而使任务在规定时间内无法完成.
在平时学习C语言时,注意知识地全面性,C语言大作业所需地知识相当全面,所
以平时地积累也是相当重要地.
在团体编写程序过程中,我们自身也应具备相当多地素质:我们肯下功夫,有恒心,有毅力地精神,在完成C语言地过程中往往有地错误不是一眼就能看出来地,我们要善于思考,而且思考地要尽量全面.第一,我们要完成自己所需要完成地模块,在完成过程可能会出现很多麻烦地错误,在自己努力修改后还是没能修改出来时,我们应积极讨论,不应放弃,询问合作者,如果两人都无法修改地话,就想老师求助.在模块整合时,往往会出现相当多地问题,每个人有每个人地设计理念,可能想法上会发生分歧,这时我们应冷静地交流,取最佳地想法,实现模块地成功整合.可能同一组地成员之间编写C语言地能力有差异,优秀地人在完成自己任务后也应辅导帮助其他人完成他们地任务,C语言大作业,完成地好坏不是靠个人地力量,是集体.而且在评价C语言大作业时,也不是拿出个人地模块来评价,也是直接评价这个组队完成地情况.
八.建议;
一、C语言大作业是一项有助于我们整合所学知识以及培养我们编写程序能力地工作,编程虽然辛苦,但是学到东西很多,它将我们所学知识成功运用到生活中去,也有利于我们组员之间地合作能力,将编程方式应与我们平时教案联系在一起,在老师地指导下,提供我们更多这样地机会.
二、可以拓展我们地知识层面,将我们C语言编写地功能进一步深入,可能我们知识有限,不能成功完成任务,我们可以通过自己看书以及求助同学来完成任务.
三、讲解一些实用性地程序,如<密码地设定,清屏,获取时间日期等),拓展我们关于实用性语言方面地知识,能在编写一些关于生活方面地应用型程序时,我们有足够地知识来完成.。