资源描述
C语言集中上机报告车票管理系统 院 系: 计算机学院 班 级: xxx 姓 名: xxx 合 作 者: 无 指导教师: xxx 2009年 6月 11日目 录一概述3二总体方案设计3三详细设计5四程序的调试与运行结果说明8五课程设计总结10六后记10七附录11参考文献20一 概述1. 课程设计的目的熟练掌握C语言的应用及特点; 掌握函数声明、定义和使用的方法;熟练掌握C语言中的对文件进行操作的基本方法;熟练掌握结构体的使用方法;掌握链表的基本操作。2. 课程设计的要求1.要求利用C语言面向过程的编程思想完成系统设计;2.突出C语言的函数特征,以多个函数实现每一个子功能;3.画出功能模块图;4.进行简单的界面设计,能够实现友好交互;5.具有清晰的程序流程图和数据结构的详细定义;6.源码格式规范,要有适当的注释,使程序容易阅读。3. 课程设计的主要设计思想这次设计的车票管理系统,实现了对车票的实时管理,功能包括录入、增加班次信息(信息用文件保存),浏览班次信息,查询路线以及售票和退票功能。主要使用了链表实现了数据的保存和修改,同时使用文件相关函数对文件进行同步。二 总体方案设计这个程序比较简单,主要分为菜单,浏览/查询,售票/退票,和增加数据四个部分。采用了链表作为存储的方式,并实现了结构体与文件的同步修改,已经具备了题目要求的所有功能。这个程序由我个人完成。在编程过程中遇到的关键问题有系统时间的获取与显示,从文件中读取链表,处理每天班次的人数刷新问题,以及如何提高代码的复用率等。程序整体框图如下:启动程序文件是否存在5增加新班次记录结构体链表文件是否为空否是是修改3查找班次4退出系统数据文件banci.dat修改菜单1-5否关闭文件将文件读入结构体链表更新班次日期等读取写入修改1显示班次读取调用2售票 / 退票调用判断是否能够售票/退票(根据时间,已订票人数)是修改三 详细设计程序结构以及各函数的具体功能main.c:void main();程序入口,对文件进行打开和初始化后进入菜单void menu(struct banci *head,struct banci *nw,FILE *data,unsigned int serial);显示菜单,从主函数中得到各种信息,通过switch语句调用其他功能operate.c:void update(struct banci *ut,FILE *data);更新结构体中的各个数据,主要对日期进行处理,当班次更新后重新写入日期并将已订票人数清零void displaybanci(struct banci *head, unsigned short mode);作为整个程序中唯一的数据显示函数,显示班次信息,有3个显示模式struct banci * addbanci(struct banci * tail, FILE *data,unsigned serial);增加一条新的班次信息到链表末尾,并写入文件void searchbanci(struct banci * head);查找班次信息,可按班次号查询或按终点站查询void piao(struct banci *head,FILE *data);实现售票和退票功能,并自动更新文件operate.h声明结构体和各个自定义函数部分函数的算法分析1. 对文件进行打开和初始化。这个功能在主函数main()中完成。有关代码如下,具体功能解释在程序注释中。FILE *data;struct banci *head,*nw;head=(struct banci*)malloc(sizeof(struct banci);if(data=fopen(banci.dat,r+)=NULL)data=fopen(banci.dat,w);printf(nn建立新文件,请至少输入一条班次记录n);nw=addbanci(head,data,1);head=nw;else if(fread(head,sizeof(struct banci),1,data)=0)/判断文件是否为空。fread()返回的是读取成功的数据块数目,返回0说明读取失败。若文件不为空则实现读取文件printf(nn数据文件是空的,请至少输入一条班次记录n);nw=addbanci(head,data,1);head=nw;elsenw=head;while(1) /把整个链表从文件中读出来,同时获取目前的班次总数serial+;/if(nw-next=NULL) break; /这么判断结尾时不可行的,因为nw-next已经被赋值不可能为空了nw-next=malloc(sizeof(struct banci);if(fread(nw-next,sizeof(struct banci),1,data)=0)/逐条读取。若遇到结尾,结束读取nw-next=NULL;break;nw=nw-next;2. update() 函数。使用这个函数主要是考虑到系统日期变化后对班次的售票信息进行更新。在程序中每进入一次菜单就要执行一次update()函数。当结构体中存储的年月日和系统目前的时间都相等是则跳过并不清零已订票人数,否则对结构体进行更新并清零已订票人数。主要代码如下:if(nowtime.wYear = ut-fache.wYear &nowtime.wMonth = ut-fache.wMonth &nowtime.wDay = ut-fache.wDay )fseek(data,sizeof(struct banci),1); /不需要更新,则跳过这个结构体,不写文件elseut-fache.wYear=nowtime.wYear;ut-fache.wMonth=nowtime.wMonth;ut-fache.wDay=nowtime.wDay;ut-fache.wDayOfWeek=nowtime.wDayOfWeek;ut-yidingpiaorenshu=0;fwrite(ut,sizeof(struct banci),1,data);3. displaybanci() 函数。通过显示模式这一变量,实现了代码的重复利用。当显示整个链表时,循环显示所有信息;当在查找中仅需要显示单条记录时,不再继续显示之后的信息。这是有关显示模式的主要代码:while(head!=NULL) if (mode=1 | mode=3) /显示全部记录时,继续显示 head=head-next; if (mode=2) /显示单条记录时,不再显示 break;if(mode=1) getch(); /模式2和3不需要暂停,故有这个判断4. 关于班次的序列号。这个程序中班次是固定的,不需要修改或删除,故班次的序号又系统自动分配,不需要输入。在程序开始初始化文件时,就获取了目前的班次总数,若再增加班次,则序列号自动加一。具体实现:(菜单menu()中)case 5: serial+;nw=addbanci(nw,data,serial); break;(addbanci()中)newnode-serial=serial;四 程序的调试与运行结果说明1. 启动程序,提示输入第一条记录建立文件建立新文件,请至少输入一条班次记录这是第 1 个班次输入发车时间(小时:分钟)2. 若文件为空,也提示输入第一条记录数据文件是空的,请至少输入一条班次记录这是第 1 个班次输入发车时间(小时:分钟)3. 输入记录后进入菜单,使用了简单的文本菜单界面C题目二十三: 车票管理系统今天是 2009 年 6 月 12 日,目前读取的时间为 8 时 37 分 1. 浏览班次信息 2. 售票 / 退票 3. 查询班次 4. 退出系统 5. 增加班次4. 浏览班次信息浏览班次班次 发车时间 起点站 终点站 行车时间 额定载量 已定票人数 是否已发出1 8 : 00 aaa bbb 0.5 40 0 已发出2 23 : 00 bbb aaa 0.5 40 23 12 : 00 rtf bbb 1.5 40 14 17 : 30 bbb rtf 1.5 40 05 19 : 30 ttt rtf 0.3 40 06. 查询班次信息,按终点站查询查询班次 1. 按班次号查询 2. 按终点站查询输入要查询的终点站: bbb浏览班次班次 发车时间 起点站 终点站 行车时间 额定载量 已定票人数 是否已发出1 8 : 00 aaa bbb 0.5 40 0 已发出浏览班次班次 发车时间 起点站 终点站 行车时间 额定载量 已定票人数 是否已发出3 12 : 00 rtf bbb 1.5 40 17. 售票、退票,以售票为例浏览班次班次 发车时间 起点站 终点站 行车时间 额定载量 已定票人数 是否已发出1 8 : 00 aaa bbb 0.5 40 0 已发出2 23 : 00 bbb aaa 0.5 40 23 12 : 00 rtf bbb 1.5 40 24 17 : 30 bbb rtf 1.5 40 05 19 : 30 ttt rtf 0.3 40 0售票 / 退票 1. 售票 2. 退票输入要售票的班次号:3第 3 班次完成一次售票8. 增加班次信息这是第 6 个班次输入发车时间(小时:分钟)10:15输入起点站ytr输入终点站aaa输入行车时间(分钟)60输入额定载量32五 课程设计总结经过测试,这个系统已经达到了题目中的全部要求。从功能上讲,这个程序还有不完善的地方,如不能修改或删除班次信息等。另外,由于追求代码复用率的原因,在查询班次时会显示出多余的信息,有待进一步改进。这个程序有一个特点就是界面简明,但从另一方面讲也可以说是界面简陋,如果可能的话,下一个版本将采用图形界面。在编程过程中也遇到了一些困难,如系统时间的获取与保存,从文件中读出整个链表等,这些都通过查询资料和询问同学得到了解决。另外在程序测试过程中发现了发车后订票人数不能归零的问题,后来通过添加update()函数得到了解决。六 后记经过这次集中上机实习,我充分认识到了C语言的用途是非常广的,功能也非常强大,是学计算机不可缺少的语言。更重要的是,在这次编程中熟悉了编写一个比较复杂程序的流程,以及发现问题、解决问题的能力,为下一步计算机语言的学习做了准备。之前感觉遥不可及的功能,现在可以实现了,应当感谢老师和同学的热心帮助,这是我得以及时完成这个程序的重要因素。七 附录main.c#include#include#include#includeoperate.hunsigned int serial=0; /班次序列号,由系统自动生成不能修改void menu(struct banci *head,struct banci *nw,FILE *data,unsigned int serial);void main()FILE *data;struct banci *head,*nw;/system(mode con cols=80 lines=25);/定义屏幕宽度head=(struct banci*)malloc(sizeof(struct banci);if(data=fopen(banci.dat,r+)=NULL)data=fopen(banci.dat,w);printf(nn建立新文件,请至少输入一条班次记录n);nw=addbanci(head,data,1);head=nw;else if(fread(head,sizeof(struct banci),1,data)=0)/判断文件是否为空。fread()返回的是读取成功的数据块数目,返回0说明读取失败。若文件不为空则实现读取文件printf(nn数据文件是空的,请至少输入一条班次记录n);nw=addbanci(head,data,1);head=nw;elsenw=head;while(1) /把整个链表从文件中读出来,同时获取目前的班次总数serial+;/if(nw-next=NULL) break; /这么判断结尾时不可行的,因为nw-next已经被赋值不可能为空了nw-next=malloc(sizeof(struct banci);if(fread(nw-next,sizeof(struct banci),1,data)=0)/逐条读取。若遇到结尾,结束读取nw-next=NULL;break;nw=nw-next;menu(head,nw,data,serial);void menu(struct banci *head,struct banci *nw,FILE *data,unsigned int serial)char kinput;while(1)system(cls);printf(C题目二十三: 车票管理系统);update(head,data);printf(n 1. 浏览班次信息n 2. 售票 / 退票n 3. 查询班次n 4. 退出系统n 5. 增加班次nn);kinput=getch();switch(kinput)case 1: displaybanci(head,1);break;case 2: piao(head,data);break;case 3: searchbanci(head);break;case 4: fclose(data);exit(0);case 5: serial+;nw=addbanci(nw,data,serial); break;default:;oprate.c#include#include#include#includeoperate.hvoid update(struct banci *ut,FILE *data) /防止第二天定票人数不归零的情况发生SYSTEMTIME nowtime;GetLocalTime(&nowtime);printf(n今天是 %d 年 %d 月 %d 日,目前读取的时间为 %d 时 %d 分n,nowtime.wYear,nowtime.wMonth,nowtime.wDay,nowtime.wHour,nowtime.wMinute);rewind(data);for(;ut!=NULL;ut=ut-next)if(nowtime.wYear = ut-fache.wYear &nowtime.wMonth = ut-fache.wMonth &nowtime.wDay = ut-fache.wDay )fseek(data,sizeof(struct banci),1);/不需要更新,则跳过这个结构体,不写文件elseut-fache.wYear=nowtime.wYear;ut-fache.wMonth=nowtime.wMonth;ut-fache.wDay=nowtime.wDay;ut-fache.wDayOfWeek=nowtime.wDayOfWeek;ut-yidingpiaorenshu=0;fwrite(ut,sizeof(struct banci),1,data);void displaybanci(struct banci *head, unsigned short mode) /承担所有的链表显示,有3个显示模式SYSTEMTIME nowtime;GetLocalTime(&nowtime);printf(浏览班次n);printf(班次 发车时间 起点站 终点站 行车时间 额定载量 已定票人数 是否已发出n);while(head!=NULL)printf(%-4d %2d : %02d %-10s%-10s%-10.1f%-9d%-3d ,head-serial,head-fache.wHour,head-fache.wMinute,head-qidian,head-zhongdian,(float)head-shijian/60,head-edingzailiang,head-yidingpiaorenshu);if( nowtime.wHourhead-fache.wHour| (head-fache.wHour=nowtime.wHour & nowtime.wMinutehead-fache.wMinute)head-shifouyifachu=1;printf( 已发出n);head-yidingpiaorenshu=0;elsehead-shifouyifachu=0;printf( n); if (mode=1 | mode=3) /显示全部记录时,继续显示 head=head-next; if (mode=2) /显示单条记录时,不再显示 break;if(mode=1) getch(); /模式2和3不需要暂停,故有这个判断struct banci * addbanci(struct banci * tail, FILE *data,unsigned serial)struct banci *newnode;newnode=(struct banci*)malloc(sizeof(struct banci);GetLocalTime(&newnode-fache); /先调出系统时间printf(n这是第 %d 个班次n,serial);printf(输入发车时间(小时:分钟)n);scanf(%d:%d,&newnode-fache.wHour,&newnode-fache.wMinute);printf(输入起点站n);scanf(%s,newnode-qidian);printf(输入终点站n);scanf(%s,newnode-zhongdian);printf(输入行车时间(分钟)n);scanf(%d,&newnode-shijian);printf(输入额定载量n);scanf(%d,&newnode-edingzailiang);newnode-yidingpiaorenshu=0;/这两个变量由系统自动指定无需输入newnode-serial=serial;tail-next=newnode;/连接链表newnode-next=NULL;fwrite(newnode,sizeof(struct banci),1,data);/更新文件fflush(data);return newnode;void searchbanci(struct banci * head)char sinput;unsigned sserial;char szhongdian8;unsigned short label=0;printf(查询班次nn 1. 按班次号查询n 2. 按终点站查询n);sinput=getch();switch(sinput)case 1: printf(输入要查询的班次: );scanf(%d,&sserial);for(;head!=NULL;head=head-next)if(head-serial=sserial)label=1;displaybanci(head,2);break;case 2: printf(输入要查询的终点站: );scanf(%s,szhongdian);for(;head!=NULL;head=head-next)if(strcmp(szhongdian,head-zhongdian)=0)label=1;displaybanci(head,2);break;default:;if(label=0)printf(n没有找到或无法操作n);getch();void piao(struct banci *node,FILE *data)char pinput;unsigned int pserial;unsigned short label=0;displaybanci(node,3);printf(售票 / 退票);printf(n 1. 售票n 2. 退票n);pinput=getch();switch(pinput)case 1:printf(输入要售票的班次号:);scanf(%d,&pserial);for(;node!=NULL;node=node-next)if(node-serial=pserial)if(node-shifouyifachu=0 & node-yidingpiaorenshuedingzailiang)node-yidingpiaorenshu+;fseek(data,(pserial-1)*sizeof(struct banci),0);fwrite(node,sizeof(struct banci),1,data);label=1;printf(n第 %d 班次完成一次售票n,pserial);break;case 2:printf(输入要退票的班次号:);scanf(%d,&pserial);for(;node!=NULL;node=node-next)if(node-serial=pserial)if(node-shifouyifachu=0 & node-yidingpiaorenshu!=0)node-yidingpiaorenshu-;fseek(data,(pserial-1)*sizeof(struct banci),0);fwrite(node,sizeof(struct banci),1,data);label=1;printf(n第 %d 班次完成一次退票n,pserial);break;default:;if(label=0)printf(n没有找到,或无法操作n);getch();oprate.hstruct banciunsigned int serial;SYSTEMTIME fache;char qidian10;char zhongdian10;unsigned int shijian;/行车时间用分钟数保存unsigned int edingzailiang;unsigned int yidingpiaorenshu;unsigned short shifouyifachu;struct banci *next;void displaybanci(struct banci *head, unsigned short mode);struct banci * addbanci(struct banci * tail, FILE *data,unsigned serial);void searchbanci(struct banci * head);void piao(struct banci *head,FILE *data);void update(struct banci *ut,FILE *data);参考文献1 谭浩强,C程序设计题解与上机指导(第二版),北京,清华大学出版社,2000年9月。2 甘玲 ,解析C程序设计,北京,清华大学出版社,2007年3月。
展开阅读全文