目 录
1. 课程设计介绍 ........................................................................1
1.1设计背景 ........................................................................1 1.2课程设计内容 ....................................................................1 1.2课程设计要求 ....................................................................1 1.3.课程设计指导思想 ...............................................................2 2. 方案论证 ............................................................................2
2.1设计原理 ........................................................................2 2.2选择方案 ........................................................................2 2.3选择方案的原因 ..................................................................2 2.4方案特点 ........................................................................3 3. 设计过程论述 ........................................................................3
3.1概要论述 ........................................................................3
3.1.1系统总体论述(总体结构框图及说明) ..........................................3 3.1.2各子模块论述 ..............................................................4 3.2详细论述 .......................................................................11
3.2.1 预处理模块 ..............................................................11 3.2.2main()函数 ...............................................................13 3.2.4searchtrain(l)函数 .......................................................27 3.2.5 BookTicket(l,k)函数 .....................................................32 3.2.6RefundTic(l,k)函数 .......................................................35 3.2.7SaveTrainInfo(l)函数和SaveBookInfo(k)函数 ................................38
4. 软件测试 ...........................................................................43
4.1主程序设计思路及运行结果截图 ...................................................43
4.1.1主程序设计思路 ...........................................................43 4.1.2运行结果截图 .............................................................44 4.2功能测试 .......................................................................44
4.2.1录入火车信息模块功能测试截图 .............................................44 4.2.2查询模块功能测试截图 .....................................................45 4.2.4退票模块功能测试截图 .....................................................46
5. 总结 ...............................................................................47
5.1调试过程记录 ...................................................................47 5.2课程设计心得体会 ...............................................................48
参考文献
1. 课程设计介绍 1.1设计背景
随着科技的飞速发展,出行的旅客越来越多,在车站窗口排队买票已经满足不了用户的需求.因此火车订票系统应用而生,该系统实现了火车车次信息的查询/显示功能,可以帮助用户方便快捷的预定车票,还可以对用户订票信息进行保存
1.2课程设计内容
设计开发一种火车订票系统。通过此系统可以实现以下功能:
a.录入车票的详细信息(包括车次编号、出发时间、出发站、到达时间、到达站等,还需要保存这些信息)
b.查询车票的详细信息(可按站点和车次查询,显示查询的详细信息,选择余票显示详细的信息如车厢号座位号)
c.订购火车票(订票时要提供火车详细信息以及订票人的姓名证件号以及订票数,可预订剩余座位号中用户感兴趣的座位)
d.火车票退票(退票后要修改相关数据;客户资料有姓名证件号,退票后要计算余票数量)
e.保存的信息(保存火车的信息及订票人的信息)
1.2课程设计要求
根据上述课程设计内容,灵活运用数据结构与算法设计火车订票系统,实现上述全部目标.要求对软件技术的各个组成部分的基础知识、发展趋势有全面、系统的了解。掌握基本数据结构,达到能熟练运用解决实际问题的程度。掌握操作系统基本原理和类型,了解系统各种管理功能。通过自学了解软件工程的基本概念,软件设计开发的过程和相关技术。 仅限C语言进行编程.
课程设计说明书中必须提供以下内容: 课程设计介绍(内容和设计要求)
a.概要设计(系统总体结构框图及详细说明,以及各子模块功能详细分析及模块执行流程图)
b.详细设计(每个模块所涉及的所有函数的分析、流程图、对应的源代码)
第 1 页 共 50 页
c.软件测试(主程序及各子模块对应的运行结果截图) d.总结(设计中出现的问题及解决办法,设计心得体会)
1.3.课程设计指导思想
结构化程序设计方法。将火车订票系统的设计分阶段进行,该火车订票系统的设计主要采用了模块化设计、结构化编码、自顶向下、逐步细化等方法.
选用链式存储结构存储火车信息及客户的信息。每个模块设计自定义函数来实现各模块的目标
2. 方案论证 2.1设计原理
本设计通过链表和函数实现火车订票系统的各种功能,首先将系统结构化,即将系统分成若干子模块,然后利用各种函数来分别实现每一个功能模块。
主函数的设计:定义menu()函数实现显示选择菜单的功能,应用switch多分支选择结构
来实现对菜单中功能的调用
录入车票设计:使用strcmp()比较函数判断车次是否存在。 查询模块设计:便利链表来查找是否存在满足条件的信息、
订票模块设计:同样使用了strcmp()比较函数来对输入的信息进行检索匹配,要注意的
是订票成功后需对票数进行计算。
退票模块设计:退票成功后同样需对票数进行计算。该模块也使用了比较函数,在退票
时比较订票人的姓名与证件号来判断操作是否可行。
保存模块设计:主要应用文件处理来将火车信息和订票人信息保存到指定的磁盘文件中。
最后通过主函数将各个功能功能模块连接起来。
2.2选择方案
在设计之前定义存储火车信息和订票人信息的结构体以及一些宏定义。在各个模块中根据课设内容以及上面的设计原理自定义实现模块的函数,最后在主程序中引用这些函数,即可实现火车票的录入、查询、订票、退票以及这些信息的保存。
2.3选择方案的原因
在上述方案中首先应用了结构化程序设计方法。结构化的程序便于编写、阅读、修
第 2 页 共 50 页
改和维护,尤其是在修改时不需要改动整体,只需在模块内修改即可这就减少了程序出错的机会,提高了程序的可靠性,保证了程序的质量。
选用链式的存储结构,在使用链表前不需要事先估计存储空间的大小,而且火车订票系统需进行频繁的插入、删除操作,使用链表不需要移动大量元素。
2.4方案特点
结构化的程序使得系统结构清晰、层次分明,作者容易写,读者容易看。如果发现某一部分中有一段内容不妥,需要修改,只需找出该部分,修改有关部分即可,与其他部分无关
链式的存储结构虽然在前期处理比较麻烦,但是在后期的插入、删除操作中非常方便。
3. 设计过程论述 3.1概要论述
3.1.1系统总体论述(总体结构框图及说明)
火车订票系统主要由录入火车信息、查询火车票信息、订票、退票、保存信息五个模块组成。火车订票系统的主要功能结构如下图所示。
火车订票系统 录入火车信息
查询火车信息 保存信息 订票退票
第 3 页 共 50 页
为了提高程序的可读性,在预处理模块中做了充足的准备工作。在该模块中宏定义了频繁用到的输入输出语句中的字符串,也使用了自定义结构体类型封装了其中存在的不同
票数 类型的离散数据。预处理模块定义了以下几种结构:
座位号数据域 节点结构票价指针域 火车信息到达时间 出发站订票人信息 (1)预处理模块
3.1.2各子模块论述
出发时间
车次编号
姓名证件号联系电话 到达站订票数 第 4 页 共 50 页
(2)主函数设计
在C程序中,执行从主函数开始,调用其他函数后流程返回到主函数,在主函数中结束整个程序的编写。
火车订票系统在主函数中主要实现了显示选择菜单的功能和完成对选择菜单功能的调用。火车订票系统的程序运行后,首先进入到选择菜单在这里列出了程序中的所有功能。用户可以根据需要输入想执行的功能编号,在提示下完成操作,实现订票当输入相应编号后,程序会根据该编号调用相应的功能函数,具体的选择菜单列表如下图所示。
编号 0 1 2 3 4 5
主函数的模块执行流程图如下:
第 5 页 共 50 页
功能 退出系统 录入火车票信息 查询火车票信息 订票 退票 保存火车信息和订票人信息
Sel=1 Int sel 开始 输入sel的值 是 Traininfo(l);
否
否 Sel=2 是 Searchtrain(l); 否 Sel=3 是 Booktickets(l,k); 否 Sel=4 是 Refundtic(l,k); 否 Sel=5 是 Savetraininfo(l); Savebookinfo(k); 是 是 是否保存
Sel=0
第 6 页 共 50 页
否 结束
(3)录入车票设计
在火车订票系统中添加一个火车票信息,首先根据提示输入车次,并判断车次是否存在,当不存在时才继续输入火车票其他信息,将信息插入链表节点中。具体流程图如下:
开始
输入火车编号
是 车次是否存在
结束 否 开辟一个动态内存 将信息插入链表中 输入出发站
输入到达站 复制火车编号 输入票数
输入火车票价格 输入到达时间 输入出发时间
(4)查询模块设计
查询模块主要用于根据输入的火车车次或者城市来进行查询。如果存在该信息则以简洁的表格形式输出满足条件的火车票信息。具体流程图如下:
第 7 页 共 50 页
开始
是否有保存的火车信息 否
是 输出:请录入火车信息后进行查询
按车次查询 选择查询方式
按站点查询 输入车次编号
输入到达站 遍历存储火车信息的链表 遍历存储火车信息的链表
结束
是否有与输入的车号相匹配的火车 否 否 是否有与输入的站名相匹配的火车 是 是
输出:没有您所查询的火车信息 输出火车信息
第 8 页 共 50 页
输出火车信息
(5)订票模块设计
订票模块用于根据用户输入的城市进行查询,在屏幕上显示满足条件的火车票信息,从中选择自己想要预定的车票,并根据提示输入个人信息。具体流程图如下:
开始
输入到达站
遍历链表
是否有与输入站点匹配的火车 是 输出所有满足条件的火车信息 否 否 输出:没有您所找的火车信息
是 是否要订票 输入姓名证件号 余票数减输出:订票成功
结束 输入车次编号 输入要预定的票数 余票是否为0
是 输出余票数量
输出:对不起!火车票已售完 第 9 页 共 50 页
(6)退票模块设计
退票时首先输入车次号与证件号判断是否订过车票,车票全部退完是要将订票信息清空,及将车次号改为空.退票成功要计算火车的余票数量。
开始
输入要退的票的车次号
是 是否有与车次匹配的火车 否
输入证件号 输出:退票失败
是否有匹配的证件号 否
结束 是 输入要退的票数
计算余票 车票是否全部退完 是
将车次号改为空 否 输出退票成功
第 10 页 共 50 页
(7)保存模块设计
保存模块主要应用文件处理来将火车信息和订票人信息保存到指定的磁盘文件中,首先要将磁盘文件以二进制写的方式打开。然后读取文件信息判断文件是否正确写入。 具体流程图如下:
开始
打开只写的二进制文件 否 文件是否为空 是
结束 遍历链表 输出:文件打开失败 保存信息
关闭文件 3.2详细论述
3.2.1 预处理模块
预处理模块中,只定义了字符串与结构体以及.输出的选择菜单格式,相关代码如下:
#define HEADER1 \" ----------------------火车订票系统------------------ -------\\n\" #define HEADER2 \" |列车号 |出发站 |到达站 |出发时间 |到达时间 |票价 |票数 |\\n\" #define HEADER3 \" |-------|-------|-------|---------|---- ----|------|-------|\\n\" #define FORMAT \" | %-10s | %-10s | %-10s | %-10s | %-10s | %5d | %5d |\\n\" #defineDATAp->data.num,p->data.startcity,p->data.reachcity,p->data.takeofftime,p->data.receivetime,p->data.price,p->data.ticketnum
第 11 页 共 50 页
/*定义存储火车信息的结构体*/ struct train {
char tnum[10]; /*列车号*/ char startcity[10]; /*出发城市*/ char reachcity[10]; /*目的城市*/ char takeofftime[10]; /*发车时间*/ char receivetime[10]; /*到达时间*/ int price; /*票价*/
int ticketnum; /*票数*/ int seats[100]; /*座位号*/ };
/*订票人的信息*/ struct man {
char num[20]; /*证件号*/ char name[10]; /*姓名*/
char tel[11]; /*联系电话*/ int bookNum ; /*订的票数*/ };
/*定义火车信息链表的结点结构*/ typedef struct node {
struct train data ; /*数据域*/ struct node * next ; /*指针域*/ }Node,*Link ;
/*定义订票人链表的结点结构*/
第 12 页 共 50 页
typedef struct Man {
struct man data ; struct Man *next ; }book,*bookLink ; /* 初始界面*/ void menu() {
puts(\"\\n\\n\\n\\n\");
puts(\"\\|------------------------------------------------------|\"); puts(\"\\| 欢迎进入火车订票系统 |\"); puts(\"\\|------------------------------------------------------|\"); puts(\"\\| 按0:退出系统 |\"); puts(\"\\| 按1:输入火车票信息 |\"); puts(\"\\| 按2:查找火车票信息 |\"); puts(\"\\| 按3:订购火车票 |\"); puts(\"\\| 按4: 退票 |\"); puts(\"\\| 按5:查看保存的订票人信息和火车信息 |\"); puts(\"\\|------------------------------------------------------|\"); }
3.2.2main()函数
在主函数中使用了fopen()函数,因为在主函数中打开文件是为了将火车票信息和订票人信息保存到该文件中,需要首先判断文件中是否有内容。 Fopen() 函数名 打开文件函数 入口参数 文件路径及文件名,读写方式 Fopen()函数流程图如下所示:
出口参数 指向文件的指针
第 13 页 共 50 页
关闭文件 从指定文件中读取记录 是 文件是否为空 否 feof() (文件是否到结尾) 否 开辟一个动态内存 是 Fopen() (以二进制打开文件train.txt) 开始
函数实现代码如下:
fp1=fopen(\"f:\\\rain.txt\以二进制的方式打开存储车票信息的文件,允许读/写*/ if((fp1==NULL)) {
printf(\"文件打开失败!\"); return 0 ; }
while(!feof(fp1)) //若文件中有数据则执行,feof为检测流上的结束符 {
第 14 页 共 50 页
结束
p=(Node*)malloc(sizeof(Node));
if(fread(p,sizeof(Node),1,fp1)==1) /*从fp1中读取单位长度为sizeof(node)的文件赋给p,与1比较*/ {
p->next=NULL ;
r->next=p ;/*构造链表*/ r=p ; } }
fclose(fp1); //无数据则关闭文件 fp2=fopen(\"f:\\\\man.txt\ if((fp2==NULL)) {
printf(\"文件打开失败!\"); return 0 ; }
while(!feof(fp2)) {
t=(book*)malloc(sizeof(book)); if(fread(t,sizeof(book),1,fp2)==1) {
t->next=NULL ;
h->next=t ; //构造链表 h=t ; } }
fclose(fp2); //关闭文件 if((fp1==NULL)) {
printf(\"文件打开失败!\");
第 15 页 共 50 页
return 0 ; }
while(!feof(fp1)) //若文件中有数据则执行,feof为检测流上的结束符 {
p=(Node*)malloc(sizeof(Node));
if(fread(p,sizeof(Node),1,fp1)==1) /*从fp1中读取单位长度为sizeof(node)的文件赋给p,与1比较*/ {
p->next=NULL ;
r->next=p ;/*构造链表*/ r=p ; } }
fclose(fp1); //无数据则关闭文件 fp2=fopen(\"f:\\\\man.txt\ if((fp2==NULL)) {
printf(\"文件打开失败!\"); return 0 ; }
while(!feof(fp2)) {
t=(book*)malloc(sizeof(book)); if(fread(t,sizeof(book),1,fp2)==1) {
t->next=NULL ;
h->next=t ; //构造链表 h=t ; }
第 16 页 共 50 页
}
fclose(fp2); //关闭文件
主函数的完整代码如下所示:
#include #include #include FILE*fp1,*fp2 ; //定义文件的指针变量 Node *p,*r ; char ch1,ch2 ; Link l ; bookLink k ; book *t,*h ; int sel ; //选择菜单时要输的数 l=(Node*)malloc(sizeof(Node)); // 生成新指针 l->next=NULL ; //指针域为空 r=l ; k=(book*)malloc(sizeof(book)); k->next=NULL ; h=k ; fp1=fopen(\"f:\\\rain.txt\以二进制的方式打开存储车票信息的文件,允许读/写*/ if((fp1==NULL)) { printf(\"文件打开失败!\"); return 0 ; 第 17 页 共 50 页 } while(!feof(fp1)) //若文件中有数据则执行,feof为检测流上的结束符 { p=(Node*)malloc(sizeof(Node)); if(fread(p,sizeof(Node),1,fp1)==1) /*从fp1中读取单位长度为sizeof(node)的文件赋给p,与1比较*/ { p->next=NULL ; r->next=p ;/*构造链表*/ r=p ; } } fclose(fp1); //无数据则关闭文件 fp2=fopen(\"f:\\\\man.txt\ if((fp2==NULL)) { printf(\"文件打开失败!\"); return 0 ; } while(!feof(fp2)) { t=(book*)malloc(sizeof(book)); if(fread(t,sizeof(book),1,fp2)==1) { t->next=NULL ; h->next=t ; //构造链表 h=t ; } } fclose(fp2); //关闭文件 第 18 页 共 50 页 while(1) { system(\"cls\"); // 清屏 menu(); printf(\"\请选择要执行的操作(0~5): \"); scanf(\"%d\ /* clrscr();*/ system(\"cls\"); if(sel==0) { if(saveflag==1)/*当退出时判断信息是否保存*/ { getchar(); printf(\"\\n文件已修改!是否保存(y/n)?\\n\"); scanf(\"%c\ if(ch1=='y'||ch1=='Y') { SaveBookInfo(k); //保存订票人信息 SaveTrainInfo(l); //保存火车信息 } } printf(\"\\n欢迎下次光临\\n\"); break ; } switch(sel)/*根据输入的sel值不同选择相应操作*/ { case 1 : Traininfo(l);break ; case 2 : 第 19 页 共 50 页 searchtrain(l);break ; case 3 : Bookticket(l,k);break ; case 4 : RefundTic(l,k);break; case 5 : SaveTrainInfo(l); SaveBookInfo(k);break ; case 0: return 0; } printf(\"\\n请按任意健继续.......\"); getch(); } } 3.2.3TrainInfo(l)函数 录入火车信息函数 录入车票信息模块使用的是自定义函数,在自定义的函数中使用了比较函数strcmp()比较输入的车次是否与已保存的车次相同的,还使用了复制函数,当输入的车次号没有记录时,将车次号复制到创建的动态内存中.若有相同则不能继续录入车票信息。 (1)、traininfo()函数 函数名 Traininfo 函数的执行流程图见录入火车信息模块设计分析:第7页 (2)、strcmp()函数 第 20 页 共 50 页 入口参数 Link linkhead 出口参数 saveflag = 1 函数名 strcmp() 入口参数 s 出口参数 0 开始 char s;char num; 执行循环体后的语句 否 s 是 否 strcmp(s->data.num,num)==0 是 printf(\"车次编号为 '%s'的火车信息已存在!\\n\s = s->next ; return; 录入模块结束 对应的源代码如下: while(s) { if(strcmp(s->data.num,num)==0) { 第 21 页 共 50 页 printf(\"车次编号为 '%s'的火车信息已存在!\\n\ return ; } s = s->next ; } (3)、strcpy()函数 该函数的作用是将已经判断过没有车次信息的车号复制到存储火车信息的链表中 函数名 strcmp 该函数比较简单,流程图略. 函数的代码如下: p = (struct node*)malloc(sizeof(struct node)); strcpy(p->data.num,num); (4)、void printheader() 函数名:格式化输出表头函数 该函数没有入口参数和出口参数,在程序顺序执行到该函数时,输出在预处理模块对应的宏定义。 函数流程图如下: 入口参数 p->data.num 出口参数 num 第 22 页 共 50 页 开始 printf(HEADER1); printf(HEADER2); printf(HEADER3); 结束 函数代码如下: void printheader() /*格式化输出表头*/ { printf(HEADER1); printf(HEADER2); printf(HEADER3); } (5)、void printdata()函数 该函数是自定义函数,作用是将链表中的数据输出。 函数名 printdata() 函数流程图如下: 入口参数 *q 出口参数 FORMAT,DATA 第 23 页 共 50 页 开始 Node* p; p=q; printf(FORMAT,DATA); 结束 函数的代码如下: void printdata(Node *q) /*格式化输出表中数据*/ { Node* p; p=q; printf(FORMAT,DATA); } void Traininfo()函数的完整代码如下: void Traininfo(Link linkhead) { 第 24 页 共 50 页 struct node *p,*r,*s ; /*定义node型指针*/ char num[10]; r = linkhead ; s = linkhead->next ; while(r->next!=NULL) r=r->next ; printf(\"请输入车次编号(0-return)\"); scanf(\"%s\ if(strcmp(num,\"0\")==0) return; /*判断是否已经存在*/ while(s) { if(strcmp(s->data.num,num)==0) { printf(\"车次编号为 '%s'的火车信息已存在!\\n\ return ; } s = s->next ; } p = (struct node*)malloc(sizeof(struct node)); strcpy(p->data.num,num);/*输入车号*/ printf(\"请输入出发站名:\"); scanf(\"%s\输入出发城市*/ printf(\"请输入到达站名:\"); 第 25 页 共 50 页 scanf(\"%s\输入到站城市*/ printf(\"请输入出发时间:\"); scanf(\"%s\输入出发时间*/ printf(\"请输入到达时间:\"); scanf(\"%s\输入到站时间*/ printf(\"请输入火车票价格:\"); scanf(\"%d\输入火车票价*/ printf(\"请输入未出售的火车票的数量:\"); scanf(\"%d\输入剩余票数*/ p->next=NULL ; r->next=p ;/*插入到链表中*/ r=p ; saveflag = 1 ; } /*打印火车票信息*/ void printheader() /*格式化输出表头*/ { printf(HEADER1); printf(HEADER2); printf(HEADER3); } void printdata(Node *q) /*格式化输出表中数据*/ { Node* p; p=q; 第 26 页 共 50 页 printf(FORMAT,DATA); } 3.2.4searchtrain(l)函数 Searchtrain(l)函数是一个自定义函数.在该函数中是用了两个while循环,两个循环都是嵌套在if语句中,在while循环中又嵌套了一个if语句。 函数的信息如下: 函数名 Searchtrain(l) 函数的流程图如下: 因该函数流程图比较复杂,且函数使用了三个if语句,故将流程图分为三个。依次执行if语句,执行完三个if语句后函数结束。 void searchtrain()开始 入口参数 l 出口参数 s[k] Node *s[10],*r; Char str1[5],str2[10]; int sel,k,i=0 ; if语句1 if语句2 if语句3 结束 第 27 页 共 50 页 第一个if语句: if语句1开始 !l->next printf(\"请选择查询方式:\\n1:按车次编号查询;\\n2:按站点查询:\\n\"); printf(\"对不起!请先输入火车信息后再查询 !\"); return; scanf(\"%d\结束 if语句结束 第二个if语句: 第 28 页 共 50 页 if语句2开始 sel==2 sel==1 sel的值 printf(\"请输入车次编号:\"); printf(\"请输入要到达的站点名:\"); scanf(\"%s\scanf(\"%s\ r=l->next; r=l->next; 否 否 r!=NULL 是 strcmp(r->data.num,str1)==0 是 if语句2结束 s[i]=r; 否 r!=NULL 是 否 strcmp(r->data.num,str1)==0 是 r=r->next; s[i]=r; r=r->next; i++; i++; break; r=r->next; 第3个if语句: 第 29 页 共 50 页 if语句3结束 printheader(); for(k=0;kvoid searchtrain()函数的完整代码如下: void searchtrain(Link l) { Node *s[10],*r; int sel,k,i=0 ; char str1[5],str2[10]; if(!l->next) { printf(\"对不起!请先输入火车信息后进行查询 !\"); return ; } printf(\"请选择查询方式:\\n1:按车次编号查询;\\n2:按站点查询:\\n\"); scanf(\"%d\输入选择的序号*/ if(sel==1) 第 30 页 共 50 页 { printf(\"请输入车次编号:\"); scanf(\"%s\ r=l->next; while(r!=NULL) if(strcmp(r->data.num,str1)==0)/*检索是否有与输入的车号相匹配的*/ { s[i]=r; i++; break; } else r=r->next; } else if(sel==2) { printf(\"请输入要到达的站点名:\"); scanf(\"%s\ r=l->next; while(r!=NULL) if(strcmp(r->data.reachcity,str2)==0)/*检索是否有与输入的城市相匹配的火车*/ { s[i]=r; i++; r=r->next; 第 31 页 共 50 页 } else r=r->next; } if(i==0) printf(\"对不起!没有找到您所要查询的火车信息!\"); else { printheader(); for(k=0;kprintdata(s[k]); } 3.2.5 BookTicket(l,k)函数 (1)、BookTicket(l,k)函数,订票函数,该函数可以实现火车票的预定 函数名称 BookTicket(l,k) BookTicket(l,k)函数的流程图见第9页 (2)、strcmp( ) 在订票模块中使用了三个strcmp()函数,它们的功能个不相同。 函数名 strcmp() strcmp() strcmp() 第 32 页 共 50 页 入口参数 Link l,bookLink k 出口参数 saveflag=1 入口参数 p->data.reachcity,str ch,\"y\" r[t]->data.num,tnum 出口参数 0 0 0 strcmp()函数流程图: 开始 结束 p!=NULL 是 否 strcmp(p->data.reachcity,str)==0 是 r[i]=p; i++; 否 p=p->next ; 另外两个strcmp()函数流程图类似,在此略过。 (2)、strcpy()函数 该函数的功能是将信息复制到链表中 函数名 strcpy() strcpy() strcpy()函数流程图比较简单,在此略过。 BookTicket(l,k)函数代码如下: void Bookticket(Link l,bookLink k) { Node *r[10],*p ; char ch[2],tnum[10],str[10],str1[10],str2[10]; 第 33 页 共 50 页 入口参数 h->data.name,str1 h->data.num,str2 出口参数 data.name data.num book *q,*h ; int i=0,t=0,flag=0,dnum; q=k ; while(q->next!=NULL) q=q->next ; printf(\"请输入要到达的城市: \"); scanf(\"%s\输入要到达的城市*/ p=l->next ; while(p!=NULL) { if(strcmp(p->data.reachcity,str)==0) { r[i]=p ;/*将满足条件的记录存到数组r中*/ i++; } p=p->next ; } printheader(); for(t=0;tprintdata(r[t]); if(i==0) printf(\"\\n对不起!没有您所查找的火车信息\\n\"); else { printf(\"\\n您是否要订购火车票 if(strcmp(ch,\"Y\")==0||strcmp(ch,\"y\")==0)/*判断是否订票*/ { h=(book*)malloc(sizeof(book)); printf(\"请输入您的姓名: \"); scanf(\"%s\ strcpy(h->data.name,str1); printf(\"请输入您的身份证号: \"); scanf(\"%s\ strcpy(h->data.num,str2); 第 34 页 共 50 页 printf(\"请输入要预定的车次:\"); scanf(\"%s\ for(t=0;tif(strcmp(r[t]->data.num,tnum)==0) { if(r[t]->data.ticketnum<1)/*判断剩余的供订票的票数是否为0*/ { printf(\"对不起!该车次的火车票已全部售完\"); /*sleep(2);*/ return; } printf(\"还有 %d 张火车票未售出\\n\ flag=1; break; } if(flag==0) { printf(\"输入错误\"); /*sleep(2);*/ return; } printf(\"请输入要预定的票数: \"); scanf(\"%d\ r[t]->data.ticketnum=r[t]->data.ticketnum-dnum;/*定票成功则可订的票数减少*/ h->data.bookNum=dnum ; h->next=NULL ; q->next=h ; q=h ; printf(\"\\n恭喜您!订票成功\"); getch(); saveflag=1 ; } } } 3.2.6RefundTic(l,k)函数 第 35 页 共 50 页 该函数实现了火车票退票的功能 函数名 RefundTic(l,k) 函数流程图如下: 开始 入口参数 l,k 出口参数 data.num[0]='0' 结束 Link p_l=l->next; bookLink p_k=k->next; char tnum[10];int n; char num[20]; printf(\"请输入您要退的票的车次号\\n\") scanf(\"%s\ 否 p_l p_l=p_l->next; 是 strcmp(p_l->datanum,tnum) == 0 是 printf(\"请输入您的身份证号\\n\"); p_l->data.ticketnum+=n; p_k->data.bookNum-=n; p_k printf(\"未找结束 是 否 到用户,退票失败\\n\"); strcmp(p_k->data.num,num)==0 是 printf(\"请输入您要退票的数目: \"); scanf(\"%d\p_k = p_k->next; 否 printf(\"未找到车次,退票失败\\n\"); 否 p_l->data.tnum[0]='0'; 是 printf(\"退票成功\"); p_k->data.bookNum==0 RefundTic(l,k)函数完整代码如下: void RefundTic(Link l,bookLink k) 第 36 页 共 50 页 { Link p_l=l->next; bookLink p_k=k->next; printf(\"请输入您要退的票的车次号\\n\"); char tnum[10]; scanf(\"%s\while(p_l) { if(strcmp(p_l->data.tnum,tnum)==0) { printf(\"请输入您的身份证号\\n\"); char num[20]; scanf(\"%s\while(p_k) { if(strcmp(p_k->data.num,num)==0) { } else { } printf(\"未找到用户,退票失败\\n\"); printf(\"请输入您要退票的数目: \"); int n; scanf(\"%d\p_l->data.ticketnum+=n; p_k->data.bookNum-=n; if(p_k->data.bookNum==0) p_l->data.tnum[0]='0'; // 如果车票全部退完,将车次号改为空 //找到用户 //找到车次 printf(\"退票成功\"); return; p_k = p_k->next; } 第 37 页 共 50 页 } } } else { } p_l = p_l->next; printf(\"未找到车次,退票失败\\n\"); return; //未找到车次 3.2.7SaveTrainInfo(l)函数和SaveBookInfo(k)函数 (1)、SaveTrainInfo(l)保存火车信息函数 函数名 SaveTrainInfo(l) (2)、 SaveBookInfo(k)保存订票人信息函数 函数名 SaveBookInfo(k) 函数流程图如下: SaveTrainInfo(l) 第 38 页 共 50 页 入口参数 l 出口参数 count 入口参数 k 出口参数 count 开始 是 FILE*fp ; Node*p ; int count=0,flag=1 ; p=l->next ; fp=fopen(\"f:\\\rain.txt\\"wb\"); 否 否 p fp==NULL printf(\"文件打开失败!\"); 是 p=p->next ; count++; fwrite(p,sizeof(Node),1,fp)==1 是 flag printf(\"已保存 %d 个火车信息\\n\flag=0; 结束 否 saveflag=0 ; fclose(fp); SaveBookInfo(k) 第 39 页 共 50 页 开始 FILE*fp ; book *p ; int count=0,flag=1 ; p=k->next ; fp=fopen(\"f:\\\\man.txt\\"wb\"); 否 否 p 是 fp==NULL 是 printf(\"文件打开失败!\"); p=p->next ; count++; fwrite(p,sizeof(book),1,fp)==1 是 flag printf(\"已保存 %d 个订票信息\\n\flag=0; 否 saveflag=0 ; fclose(fp); 结束 第 40 页 共 50 页 函数实现代码如下: void SaveTrainInfo(Link l) { FILE*fp ; Node*p ; int count=0,flag=1 ; fp=fopen(\"f:\\\rain.txt\ if(fp==NULL) { printf(\"文件打开失败!\"); return ; } p=l->next ; while(p) { if(fwrite(p,sizeof(Node),1,fp)==1) { p=p->next ; count++; } else { flag=0 ; break ; 第 41 页 共 50 页 } } if(flag) { printf(\"已保存 %d 个火车信息\\n\ saveflag=0 ; } fclose(fp); } void SaveBookInfo(bookLink k) { FILE*fp ; book *p ; int count=0,flag=1 ; fp=fopen(\"f:\\\\man.txt\ if(fp==NULL) { printf(\"文件打开失败!\"); return ; } p=k->next ; while(p) { if(fwrite(p,sizeof(book),1,fp)==1) 第 42 页 共 50 页 { p=p->next ; count++; } else { flag=0 ; break ; } } if(flag) { printf(\" 已保存 %d个订票记录\\n\ saveflag=0 ; } fclose(fp); } 4. 软件测试 4.1主程序设计思路及运行结果截图 4.1.1主程序设计思路 火车订票系统开始运行后,首先进入到选择菜单,菜单中列出了程序中所有的功能,用户只需根据需要输入想要执行的功能编号,在提示下完成操作.当用户输入编号后,程序会根据该编号选择相应的语句执行来调用相应的功能函数。 第 43 页 共 50 页 4.1.2运行结果截图 直接运行程序就会出现该图片 4.2功能测试 4.2.1录入火车信息模块功能测试截图 调试方法:按照要求输入即可,火车车次信息没有特别严格的要求 若再次输入已有的火车信息,系统会提示:输入的火车信息已存在! 第 44 页 共 50 页 4.2.2查询模块功能测试截图 若已输入火车信息,则如下图所示:查询车次是可选1或2两种方式 4.2.3订票模块功能测试截图 订票后查询余票,余票减少 第 45 页 共 50 页 4.2.4退票模块功能测试截图 退票时需输入与订票时一样的信息,否则会退票失败 4.2.5保存模块功能测试截图 第 46 页 共 50 页 在主菜单中选择5,就会进入该界面 从菜单中退出时(输入0)系统会提示是否保存信息 5. 总结 5.1调试过程记录 1、退票时虽然可以退票,但是显示有点问题,并且如果还有火车票没有退订的话循环会一直进行。 2、录入火车票信息时陷入死循环,一直在录入车票信息并且没有办法返回主菜单。 解决办法: 在循环中加入break语句。使得流程跳到循环体之外,接着执行循环体下面的语句 加入break语句后系统执行过程如下图所示: 第 47 页 共 50 页 5.2课程设计心得体会 在设计火车订票系统是,虽然有c语言和数据结构的理论知识,但是却无从下手。在学习课本内容是忽略了实际操作的重要性。 因为有在网上订票的经验,对火车订票系统的了解比较深刻。在该课设设计的火车订票系统从在着许多的不足。比如火车的车次信息只可以输入一次,第二次输入系统会提示火车信息已从在,但是在实际中,一列火车不只是行驶一次,它会往返,在不同的时间有不同的余票信息。由于目前知识的掌握与实际的经验不足,虽然对火车订票系统兴趣比较浓厚,但是目前没有想到方法实现。 座位号的实现与火车信息的保存也存在着一些冲突。在该火车订票系统中为了保存火车的信息,座位号便没有办法实现。 在设计好的火车订票系统中还从在着一些漏洞,比如在选择查询方式的时候不是选1或者2,运行的时后会进入死循环,只能强制退出。类似的漏洞还有在菜单等有选择的地方,如果不按照系统要求进行输入,系统便会进入死循环。任何按键都无效。 经过一段时间的努力设计出了一个较为简单的火车订票系统,在进行设计的过程中积累了许多经验,将实际与理论联系在一起,课本上的内容有了更深刻的理解。 第 48 页 共 50 页 参考文献 【1】 谭浩强,C程序设计(第四版),清华大学出版社,2010.6 【2】 杨晓光、李兰友,数据结构实例教程,清华出版社、北京交通大学出版社,2008.12 【3】 李根福、贾丽君,C语言项目开发实录,清华大学出版社,2013.10 第 49 页 共 50 页 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- pqdy.cn 版权所有 赣ICP备2024042791号-6
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务