铁路售票系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
1. 设计内容_______________________________________________________ 1
2.概要设计_______________________________________________________ 3
3.详细设计_______________________________________________________ 5
4.程序源码_______________________________________________________ 7
5.程序运行与调试________________________________________________ 16
6.总结__________________________________________________________ 17
7.参考文献______________________________________________________ 17
1.设计内容
(1)软件名称:铁路售票系统
(2)软件开发的目标:
完善目前现有的铁路售票系统,使之能跟够上时代的发展,更能够满足乘客的需求以及方便售票员的工作。

同时通过实践来提高自己的动手能力,并增强自己对知识掌握的熟练程度。

(3)软件的应用范围:
理论上能够实现于铁路部门的售票系统,其目的在于在原有的系统基础使得铁路售票系统更加自动化,以期实现完善日常生活中铁路售票的各种缺陷。

(4)软件的数据流图:
D1 车票信息库
车票信息
出行信息
车票

信息
退款 信息
图1—2
D3 车票信息库
车票 信息
换乘
车票信息
图1—3
(5)软件的数据字典:
图2—1
2.概要设计
(1)系统功能包括:售票、退票、改签换乘、车次查询、系统管理等。

功能说明:
①在售票时设计了多种售票模式,售票员可输入班次、自定义站点编码、
站点拼音代码,即可显示经过该站点的所有可售班次,班次车辆的座位状态以图形方式直观地显示,全面支持键盘操作,对退票等常用功能提供自定义快捷键,提高工作效率;
②一个人可同时售数张相同或不同站点,相同或不同票种(全票、半票、
免票儿童)的车票,可以实现累加本次售票款,直至下次新售票开始;
③根据退票时间系统自动设置应收退票手续费。

并显示车票金额,应扣
手续费以及退票金额,并打印出退票手续费收据;退票用户应该包括两种:第一种用户是订票的旅客,订完车票的旅客,在取票前需要退票时,可以输入旅客的身份证号和车票号,完成退票过程;第二种用户是售票员,对于已经售出的车票,进行退票。

退票时,需要人工服务,所以收取票面金额20%的手续费。

④可实现异地联网售票、本地售票、互联网售票。

从网络订票功能上
分析,车票的信息应该包括列车的车次、出发地和目的地、席位的类型,票价和出发的日期时间。

预订车票时用户需要输入购票的张数,旅客和联系人资料。

为了方便旅客取得车票,系统生成取票号码,用户可以凭借此号码与身份证取得车票,并付款。

订票功能,只受理5天后到20
天之间的订票业务。

对于循环发车的车次,系统不提供订票。

订好车票的旅客,需要于开车两天前到取票点取票,否则系统将自动收回所订的车票。

(2)子集说明:
软件主要由五个模块组成,每个模块各有不同的功能。

但都能够完成特定的处理和存储功能,各模块的数据都存放在数据库中。

数据的调用和连接都由相应的程序来完成。

①售票模块:
从售票功能上分析,首先,售票系统应该能够按发车站,终到站进行打印车票。

售票时,售票员输入发车站和终到站,找到需要的车次,再填写售票数量,优惠信息和座位类型,并按优惠情况,折算票价。

其次,此售票系统应该提供出售循环车次车票的功能。

也实现按站打印车票。

按站打印车票的好处是,使消费更加透明和公平。

②退票模块:
从退票功能上分析,退票用户应该包括两种。

第一种用户是订票的旅客,订完车票的旅客,在取票前需要退票时,可以输入旅客的身份证号和车票号,完成退票过程;第二种用户是售票员,对于已经售出的车票,进行退票。

退票时,需要人工服务,所以收取票面金额20%的手续费。

当票面金额小于2元时,去掉手续费,就所剩无几了,因此系统应该不予退票。

由于车票退回系统后,需要时间卖给其他旅客,所以旅客需在开车前办理退票手续,否则系统不予退票。

③改签换乘模块:
从改签换乘功能上分析,首先,根据乘客提供的改签换成信息,调用车票信息库中的数据,以确定该选择的车次信息,再根据车次信息中票价,确定是该退款还是增收相应的票间差额。

待退款后或收完款后,打印新的车票。

但改签换乘必须在发车前完成,发车后不予改签车票。

④查询模块:
从查询功能上分析,需要分别满足三个条件查询。

第一个条件是,当只输入“车次”时,进行查询,查出车次的详细信息;第二个条件是,当只输入“发车站”和“终到站”时,系统会把所有满足条件的车次,查询出来;第三个条件是,当把“车次”,“发车站”
和“终到站”全都输入时,会把满足条件的唯一的一条记录(车次是唯一的)查询出来。

⑤系统管理模块:
从系统管理功能上分析,需要实现对优惠信息的设置与维护,管理车站信息,对车次信息的维护,实现列车票额分配,车票预售期设置,对售出的车票数进行统计,记录已售出车票的信息,显示剩余车票数。

设置本站名称和用户管理等功能。

(3)软件结构图:
图3.1
3.详细设计
(1)软件数据结构的描述:
车票=日期+价格+出发站+终点站+售票站+座号+车次+性质+编号日期=年+月+日+时+分
价格=“1”~“9999”
出发站=1{汉字}6
终点站=1{汉字}6
售票站=1{汉字}6
座号=车厢号+座位号
车次=“1”~“9999”
性质=“1”~“6” 注:如“1”表示空调硬座特快,“2”表示空调软座普快等
编号=“000000001”~“”
(2)软件程序流程图:
售票
改签换乘
退

退款 收款
(3)软件的主要算法:
status createlist_l(linklist &L) //生成链表的定义
void dataout_l(linklist &L) //打印火车票
void searchlist_traindate(linklist &L,char e1[]) //按火车出发日期查询
void searchlist_trainnum(linklist &L,char e3[]) //按班次查询
status deletelist_l(linklist L,char k1[],char k2[]) //售票功能
status listcountnum_l(linklist &L) //票数功能
status listticketprice_l(linklist &L,int count) //按票价排票
status listtrainnum_l(linklist &L,int count) //按班次排票
status insertlist_l(linklist &L,elemtype e) //退票功能
4.程序源码
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define OK 1
#define ERROR 0
#define MAX_NUM 10
#define MAX 20
#define MAX1 5
#define NULL 0
typedef int status;
struct ticket { long int ticketnumber; //票号采用长整型
char trainnum[MAX_NUM]; //车的班次
char startstation[MAX]; //起始站
char destination[MAX]; //终点站
float ticketprice; //票价
char traindate[MAX]; //火车出发日期}ticket[MAX1];
typedef struct ticket elemtype;
typedef struct lnode //管理类型重定义{ elemtype data;
struct lnode *next;
}*linklist,lnode;
void save(){FILE *fp;
int i;
fp=fopen("C:\\ticketrecord.txt","w");
if(fp==NULL){printf("\ncannot open file");
exit(0);
}
for(i=0;i<=MAX1-1;i++){
if(fwrite(&ticket[i],sizeof(elemtype),1,fp)!=1)
printf("\nfile write error");
}
fclose(fp);
}
status createlist_l(linklist &L) //生成链表的定义
{ int i;
linklist p;
FILE *fp;
fp=fopen("C:\\ticketrecord.txt","r");
if(fp==NULL){printf("\ncannot open file");
exit(0);
}
L=(linklist)malloc(sizeof(lnode)); //向内存申请一块占sizeof(lnode)字节的空间,并将这块空间的首地址交给L管理
L->next=NULL;
for(i=MAX1;i>0;i--){p=(linklist)malloc(sizeof(lnode));
if(fread(&p->data,sizeof(elemtype),1,fp)!=1)
printf("\nfile read error");
p->next=L->next;
L->next=p;
}
fclose(fp);
return OK;
}
void dataout_l(linklist &L) //打印火车票
{linklist p;
p=L->next;
printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期:");
while(p){
printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.t rainnum,p->data.startstation,p->data.destination,p->data.ticketprice, p->data.traindate);
printf("\n");
p=p->next;
}
}
void searchlist_traindate(linklist &L,char e1[]) //按火车出发日期查询{linklist p;
int count=0;
p=L->next;
while(p){if(strcmp(p->data.traindate,e1)==0){
count++;
if(count==1)
printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期\n:");
printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.t rainnum,p->data.startstation,p->data.destination,p->data.ticketprice, p->data.traindate);
}
p=p->next;
}
if(count==0)
printf("\n没有找到");
}
void searchlist_trainnum(linklist &L,char e3[]) //按班次查询
{linklist p;
int count=0;
p=L->next;
while(p){
if(strcmp(p->data.trainnum,e3)==0){ count++;
if(count==1)
printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期\n:");
printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.t rainnum,p->data.startstation,p->data.destination,p->data.ticketprice, p->data.traindate);
}p=p->next;}
if(count==0)
printf("\n没有找到");}
status deletelist_l(linklist L,char k1[],char k2[]) //售票功能{linklist p,q,r,t,b,c,d;
char a1[MAX],a2[MAX],a3[MAX_NUM];
int count=0,i;
long int j;
p=L->next;
while(p){
if(strcmp(p->data.startstation,k1)==0&&strcmp(p->data.destination ,k2)==0){
count++;
if(count==1){
printf("\n根据你要查找的起点站和终点站有以下这些票:"); printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期\n:");
}
printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.t rainnum,p->data.startstation,p->data.destination,p->data.ticketprice, p->data.traindate);
}p=p->next;
}if(count==0){printf("\n没有找到你所要查找的票:");
return ERROR;
}
else{printf("\n根据上述找到的票,请输入你想在找到的这些票中再根据哪种方式那你所需要的票:");
printf("\n**********************************");
printf("\n1.按上车时间; 2.按票号; *");
printf("\n3.按车的班次; *");
printf("\n**********************************");
d: printf("\n请输入你的选择:");
scanf("%d",&i);
switch(i){
case 1:printf("\n请输入你想买火车票的时间范围即时间的下限和上限:");
scanf("%s%s",a1,a2);
c=L->next;
q=L;
while(c){if(strcmp(a1,c->data.traindate)<=0&&strcmp(a2,c->data.traind ate)>=0&&strcmp(c->data.startstation,k1)==0&&strcmp(c->data.destinati on,k2)==0){printf("\n你要买的火车票为:"); printf("\n%ld\t%s\t%s\t%s\t%f\t%s",c->data.ticketnumber,c->data.train num,c->data.startstation,c->data.destination,c->data.ticketprice,c->d ata.traindate);
q->next=c->next;
free(c);
return OK;
} else { q=c;
c=c->next;}}
if(c==NULL) {
printf("\n没有你要的票");
return ERROR;
}
break;
case 2:printf("\n请输入你想买的票号:");
scanf("%ld",&j);
t=L->next;
b=L;
while(t){ if(t->data.ticketnumber==j&&strcmp(t->data.startstation,k 1)==0&&strcmp(t->data.destination,k2)==0){printf("\n你要买的火车票为:");
printf("\n%ld\t%s\t%s\t%s\t%f\t%s",t->data.ticketnumber,t->data.train num,t->data.startstation,t->data.destination,t->data.ticketprice,t->d ata.traindate);
b->next=t->next;
free(t);
return OK;
} else {
b=t;
t=t->next;
}}
if(t==NULL){printf("\n没有你要的票");
return ERROR;
}
break;
case 3:printf("\n请输入你要买的火车班次:");
scanf("%s",a3);
r=L->next;
d=L;
while(r){
if(strcmp(r->data.trainnum,a3)==0&&strcmp(r->data.startstation,k1)==0 &&strcmp(r->data.destination,k2)==0){printf("\n你要买的火车票为:"); printf("\n%ld\t%s\t%s\t%s\t%f\t%s",r->data.ticketnumber,r->data.train num,r->data.startstation,r->data.destination,r->data.ticketprice,r->d ata.traindate);
d->next=r->next;
free(r);
return OK;
}
else {
b=r;
r=r->next;
}
}
if(r==NULL) {printf("\n没有你要的票");
return ERROR;
}
break;
default:printf("\n输入错误");
}
goto d;
}
}
status listcountnum_l(linklist &L) //票数功能
{linklist p;
int count=0;
p=L->next;
while(p){count++;
p=p->next;
}
return count;
}
status listticketprice_l(linklist &L,int count) //按票价排票{int i,j;
i=count;
linklist p,t,h,s;
for(;i>=1;i--){
p=L->next;
t=L;
h=L;
if(i==1) continue;
if(p->data.ticketprice<p->next->data.ticketprice&&i==2) continue;
if(p->data.ticketprice>p->next->data.ticketprice&&i==2){ s=p->next;
L->next=s;
p->next=s->next;
s->next=p;
continue;
}
p=L->next;
if(p->data.ticketprice>p->next->data.ticketprice)
s=p;
else s=p->next;
p=p->next;
j=i-1;
while(p&&j>=1){
if(s->data.ticketprice<p->data.ticketprice)
s=p;
t=p;
p=p->next;
j--;
}
if(s==t) continue;
while(h->next){if(h->next==s){h->next=s->next;
s->next=t->next;
t->next=s;
break;
}
else h=h->next;
}
}
return OK;
status listtrainnum_l(linklist &L,int count) //按班次排票
{int i,j;
i=count;
linklist p,t,h,s;
for(;i>=1;i--){p=L->next;
t=L;
h=L;
if(i==1) continue;
if(strcmp(p->data.trainnum,p->next->data.trainnum)<0&&i==2) continue;
if(strcmp(p->data.trainnum,p->next->data.trainnum)>0&&i==2){ s=p->next;
L->next=s;
p->next=s->next;
s->next=p;
continue;
p=L->next;
if(strcmp(p->data.trainnum,p->next->data.trainnum)>0)
s=p;
else s=p->next;
p=p->next;
j=i-1;
while(p&&j>=1){if(strcmp(s->data.trainnum,p->data.trainnum)<0) s=p;
t=p;
p=p->next;
j--;
}
if(s==t) continue;
while(h->next){
if(h->next==s){
h->next=s->next;
s->next=t->next;
t->next=s;
break;
}
else h=h->next;
}
}
return OK;
}
status insertlist_l(linklist &L,elemtype e) //退票功能{linklist s,p;
s=(linklist)malloc(sizeof(lnode));
s->data=e;
p=L->next;
while(p->next){p=p->next;
}
s->next=p->next;
p->next=s;
return OK;
}
void main(){int x,y,w,z,h;
elemtype k;
long int j;
float a;
char e[MAX],b[MAX],c[MAX],d[MAX_NUM],f1[MAX],f2[MAX];
linklist myl;
printf("\n请输入车票数据:");
printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期:\n"); for(h=0;h<=MAX1-1;h++){
scanf("%d%s%s%s%f%s",&ticket[h].ticketnumber,ticket[h].trainnum,t icket[h].startstation,ticket[h].destination,&ticket[h].ticketprice,ti cket[h].traindate);
}
save();
createlist_l(myl);
printf("\n*************************************");
printf("\n*火车票管理系统: *");
printf("\n*1.查询功能; 2.售出功能; *");
printf("\n*3.退票功能; 4.打印表功能; *");
printf("\n*5.排票功能; 6.票数功能 *");
printf("\n*7.退出 *");
printf("\n*************************************");
a: printf("\n回到原火车票管理系统:");
printf("\n请输入你的选择:");
scanf("%d",&x);
switch(x){
case 1:printf("\n******************************************");
printf("\n*查询功能界面: *"); printf("\n*1.按火车出发日期查询*");
printf("\n*2.按车的班次查询*");
printf("\n*3.返回到原火车票系统 *");
printf("\n******************************************"); b: printf("\n请输入你的选择:");
scanf("%d",&y);
switch(y){
case 1: printf("\n请输入你要查询的售票日期:");
scanf("%s",e);
searchlist_traindate(myl,e);
break;
case 2: printf("\n请输入你要查找的车的班次:");
scanf("%s",d);
searchlist_trainnum(myl,d);
break;
case3: goto a;
break;
default:printf("\n输入错误");}
goto b;
break;
case 2:printf("\n请输入你要买的火车票的起点站和终点站:");
scanf("%s%s",f1,f2);
if(deletelist_l(myl,f1,f2)){
printf("\n请输出售出一张火车票后的剩余火车票为:");
dataout_l(myl);
}
break;
case 3:printf("\n请输入退的这张票的内容\n票号\t班次\t起始站\t 终点站\t票价\t出发时间:\n");
scanf("%d%s%s%s%f%s",&k.ticketnumber,k.trainnum,k.startstation,k.dest ination,&k.ticketprice,k.traindate);
insertlist_l(myl,k);
printf("\n请输出退票以后的票的情况:");
dataout_l(myl);
break;
case 4:dataout_l(myl);
break;
case 5:w=listcountnum_l(myl);
printf("\n******************************************");
printf("\n*排票功能界面: *");
printf("\n*1.按票价排票; *");
printf("\n*2.按车的班次排票; *");
printf("\n*3.返回到原火车票系统 *");
printf("\n******************************************");
c: printf("\n请输入你的选择:");
scanf("%d",&z);
switch(z){
case 1:listticketprice_l(myl,w);
printf("\n经按票价排票后为:");
dataout_l(myl);
break;
case2:listtrainnum_l(myl,w);
printf("\n经按车的班次排票后为:");
dataout_l(myl);
break;
case3:goto a;
default:printf("\n输入错误");}
goto c;
break;
case 6:printf("\n现有票%d张,且这些票分别为:",listcountnum_l(myl));
dataout_l(myl);
break;
case 7:printf("\n退出程序");
exit(0);
default:printf("\n输入错误")}
goto a;
}
5.程序运行与调试
软件的调试采用黑盒测试与白盒测试相结合的方法,这样更有利于及时发现软件的错误与不足指出,以便及时加以改正,使得软件的功能更完善,同时使得软件的实用性也更强。

(1)实现的具体方法:
本软件的黑盒测试即把对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。

因此黑盒测试又叫功能测试或数据驱动测试。

黑盒测试主要是为了发现以下几类错误:
1、是否有不正确或遗漏的功能?
2、在接口上,输入是否能正确的接受?能否输出正确的结果?
3、是否有数据结构错误或外部信息(例如数据文件)访问错误?
4、性能上是否能够满足要求?
5、是否有初始化或终止性错误
白盒测试是对软件的过程性细节做细致的检查。

这种方法是把测试对象看做一个打开的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。

通过在不同点检查程序状态,确
定实际状态是否与预期的状态一致。

因此白盒测试又称为结构测试或逻辑驱动测试。

白盒测试主要是想对程序模块进行如下检查:
1、对程序模块的所有独立的执行路径至少测试一遍。

2、对所有的逻辑判定,取“真”与取“假”的两种情况都能至少测一遍。

3、在循环的边界和运行的界限内执行循环体。

4、测试内部数据结构的有效性,等等。

(2)实现长期跟踪检测:
软件的使用是一个长期的过程,有些错误和不足在早期的测试中很能发现。

因此,只能在今后的使用中不断发掘不断完善。

鉴于开发周期的关系,许多测试步骤可能有些不如意的地方,故应该对软件实现长期的跟踪,以达到最初的期望。

6.总结
虽然在此次课程设计中遇到了诸多困难,如:源码的编写,由于受自己编程水平的限制,就让我十分的头疼。

但是还好在老师和同学的帮助,以及自己的努力专研下,都得到了完美的解决。

虽然成果并不是十分的完美,但是通过自己的努力专研,最终设计出来,还是让自己感到无比的喜悦。

设计过程虽然枯燥乏味,遇到难题时,往往抓耳挠腮,浑身不爽。

但是一旦解决了,就有一种如释重负的轻松感和无比兴奋的自豪感。

实在是乐在其中啊!
在设计之前,我脑中一片空白,不知从何下手,好几天都没有任何成果。

于是,我找出软件工程和C语言的教材,从头又专心的读了一遍,对学过的知识又温故了一遍。

然后再动手做,就轻松了许多,也得心应手了许多,这才总算知道
了该怎么下手了。

通过这次动手实践,让我深刻的认识到自身的不足,以及在软件工程学习方面与别人的巨大差距。

因此,我决定要好好的把握这个假期,从基础开始再把软件工程好好的学习领悟一遍,以求百尺竿头更进一步!
7.参考文献
[1]《软件工程导论》 (第5版) 张海藩编着清华大学出版社
[2]《C程序设计》 (第三版) 谭浩强着清华大学出版社。

相关文档
最新文档