/*
系统名称:火车订票系统
1、插入一个火车信息
2、搜索火车信息
3、预定火车信息
4、修改火车信息
5、显示火车信息
6、保存火车信息
结构组成
1、火车信息结构体
2、订票人信息结构体
3、火车信息链表节点结构体
4、订票人的链表节点结构体
操作流程:
进入主界面 -》 选择菜单 -》选择基本操作 -》显示结果 -》保存信息 -》退出
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int saveflag = 0; //定义是否保存是否文件改变(全局变量) (1、表示未保存 0、表示已保存)
#define HEADER1 "---------------------------------火车订票系统-----------------------------\n"
#define HEADER2 "| 编号 | 起始城市 | 抵达城市 | 起始时间 | 到达时间 |票的价格 | 车票数量|\n"
#define HEADER3 "--------------------------------------------------------------------------\n"
#define FORMAT "%- 10s%- 10s%- 10s%- 10s%- 10s %5d %5d\n"
#define DATA q->data.num,q->data.startcity,q->data.reachcity,q->data.takeofftime,q->data.receivetime,q->data.price,q->data.ticketnum
/*定义存储火车信息的结构体*/
struct train{
char num[10]; //列车号
char startcity[10]; //出发城市
char reachcity[10]; //目的城市
char takeofftime[10]; //发车时间
char receivetime[10]; //到达时间
int price; //票价
int ticketnum; //票数量
};
/*订票人的信息*/
struct man{
char num[20]; //×××号码
char name[10]; //姓名
int bookNum; //订票的数
};
/*定义火车链表的节点结构*/
typedef struct node{
struct train data;
struct node *next;
}Node,*Link;
/*定义订票人链表的节点结构域*/
typedef struct Man{
struct man data;
struct Man *next;
}book,*bookLink;
/*初始化界面*/
void menu()
{
puts("\n\n");
puts("\t\t|----------------------------------------------------------|");
puts("\t\t| 火车订票系统 |");
puts("\t\t|----------------------------------------------------------|");
puts("\t\t| 0:退出系统 |");
puts("\t\t| 1:插入一个火车信息 |");
puts("\t\t| 2:搜索火车信息 |");
puts("\t\t| 3:预定火车票 |");
puts("\t\t| 4:修改火车信息 |");
puts("\t\t| 5:显示火车信息 |");
puts("\t\t| 6:保存信息到文件 |");
puts("\t\t|----------------------------------------------------------|");
}
//添加一个火车信息
void Trianinfo(Link linkhead)
{
struct node *p,*r,*s;
char num[10];
r = linkhead; //链表的头指针不能移动(在以后的查询中无法找到头指针)
s = linkhead->next; //链表头指针后面一个节点才开始有火车信息数据
while(r->next != NULL) //找到链表尾部
r = r->next;
while(1)
{
printf("请输入火车的编号(0-无穷大)");
scanf("%s",num);
if(strcmp(num,"0") == 0)
break;
/*判断是否存在*/
while(s /* s != NULL */)
{
if(strcmp(s->data.num , num) == 0){
printf("编号为%s的火车已存在!!\n",num);
return ;
}
s = s->next;
}
p = (struct node*)malloc(sizeof(struct node));
strcpy(p->data.num,num); //将编号存放到节点里面
printf("请输入火车开始城市 :");
scanf("%s",p->data.startcity);//输入出发城市
printf("请输入火车目的城市 :");
scanf("%s",p->data.reachcity);//输入目的城市
printf("请输入火车出发时间 :");
scanf("%s",p->data.takeofftime);//输入出发时间
printf("请输入火车到达时间 :");
scanf("%s",p->data.receivetime);//输入到达时间
printf("请输入票价:");
scanf("%d",&p->data.price);//输入票价
printf("请输入票数:");
scanf("%d",&p->data.ticketnum);//输入票数
p->next = NULL;
r->next = p; //插入到链表
r = p;
saveflag = 1;
}
}
//打印火车头信息
void printheader()
{
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
}
/*格式化输出表中的数据*/
void printdata(Node *p)
{
Node* q ;
q = p;
printf(FORMAT,DATA);
}
/*显示火车票信息*/
void showtrain(Link l)
{
Node *p;
p = l->next;//链表头指针后面一个节点才开始有火车信息数据
printheader(); //打印头部信息
if(l->next == NULL) //是否为空链表
printf("是空链表");
else
while(p != NULL)
{
printdata(p);
p = p->next;
}
}
/*查询火车信息*/
void searchtrian(Link l)
{
Node *s[10],*r; //*s[10]用来存储寻找到的对象
int sel,k,i = 0; //sel表示选择查询方式
char str1[10],str2[10];//str1用来输入火车编号 ,str2用来输入城市名称
if(!l->next){
printf("没有任何记录");
return;
}
printf("选择方式:\n 1:根据火车编号; \n 2:根据城市:\n");
scanf("%d",&sel);//输入选择的序号
if(sel == 1)//根据火车编号来查询
{
printf("输入火车编号:");
scanf("%s",str1);
r = l->next; //链表是从第二个元素开始才有数据
while(r != NULL)
{
if(strcmp(r->data.num,str1) == 0)//检索是否有与输入的编号相匹配
{
s[i] = r; //把已经找到的节点存放到定义好的结构体指针数组
i++;
r = r->next;//继续往表的后面寻找
}else
r = r->next;//继续往表的后面寻找
}
if( i == 0)
printf("找不到相对应的编号的火车");
}
else if(sel == 2)//根据城市来查询
{
printf("输入想要去的城市:");
scanf("%s",str2);
r = l->next; //链表是从第二个元素开始才有数据
while(r != NULL)
{
if(strcmp(r->data.reachcity,str2) == 0)//检索是否有与输入的编号相匹配
{
s[i] = r; //把已经找到的节点存放到定义好的结构体指针数组
i++;
r = r->next;//继续往表的后面寻找
}else
r = r->next;//继续往表的后面寻找
}
if( i == 0)
printf("找不到相对应的城市的火车");
}
printheader();
for(k = 0 ; k < i ; k++)
printdata(s[k]);
}
/*修改火车信息*/
void Modify(Link l)
{
Node *p ; //p节点从第二个节点开始(因为第二个节点才有数据)
char tnum[10],ch;//ch判断是否修改 tnum[10]火车编号的输入
p = l->next;
if(!p/* p != NULL */)
{
printf("你没有记录可以修改");
return;
}
else
{
printf("\n你想修改它么??(y/n)\n");
scanf("%c",&ch);
if(ch == 'y'|| ch == 'Y')//字符的比较
{
printf("\n输入火车编号:");
scanf("%s",tnum);
while(p != NULL)
{
if(strcmp(p->data.num,tnum) == 0)//查找与输入的编号相匹配的记录
break; //如果已经找到 我们的p肯定不为NULL
else
p = p->next;
}
if(p)//如果找到的p不为空
{
printf("输入火车的起始城市:");
scanf("%s",p->data.startcity);
printf("输入火车的目的城市:");
scanf("%s",p->data.reachcity);
printf("输入火车的起始时间:");
scanf("%s",p->data.takeofftime);
printf("输入火车的抵达时间:");
scanf("%s",p->data.receivetime);
printf("输入火车的票的价格:");
scanf("%d",&p->data.price);
printf("输入火车的票的数量:");
scanf("%d",&p->data.ticketnum);
saveflag = 1;//数据发生改变需要保存
}
else/*没有找到跳到此地*/
printf("没有找到该编号的火车");
}
}
}
/*订票模块*/
void Bookticket(Link l,bookLink k)//l是火车链表 k是人员链表
{
Node *r[10],*p;//r存放满足条件的火车信息
/*str表示输入想去城市、ch判断是否订票*,tnum 表示火车车次*/
char ch[2],tnum[10],str[10],str1[10],str2[10];
book *q,*h;
int i = 0, t = 0,flag = 0,dnum;//i 记录满足条件的火车信息的数量,t 进行循环打印火车信息 flag 标志有票 dnum 买票的数量
q = k;//将人员链表的表头赋值给q
while(q->next != NULL)
q = q->next; //遍历人员链表(添加订票人信息,从链表尾部添加)
printf("输入你想去的城市: ");
scanf("%s",str);
p = l->next;//链表的第二节点才有数据
while( p != NULL)//遍历火车信息链表
{
if(strcmp(p->data.reachcity,str) == 0)//如果找到你想去的城市
{
r[i] = p;//将满足条件的记录存到数组r中
i++;
}
p = p->next;
}
printf("\n\n记录的数量%d\n",i);
printheader();
for(t = 0 ; t < i ; t++)
printdata(r[t]);
if(i == 0)//如果没有找到你想去的城市
printf("没有你所要找的车次");
else//如果找到就订票
{
printf("\n你想要订票么?\n");
scanf("%s",ch);
if(strcmp(ch,"Y")== 0 || strcmp(ch,"y")==0)//进行字符串的比较
{
printf("请输入需要的火车车次:");
scanf("%s",tnum);
for(t = 0; t < i ; t ++)
{
if(strcmp(r[t]->data.num,tnum) == 0)
{
if(r[t]->data.ticketnum < 1)//判断剩余的供票数量是否为0
{
printf("对不起,没有票");
return;
}
printf("剩余%d张票\n",r[t]->data.ticketnum);
flag = 1;//标志有票
break;
}
}
if(flag == 1){
h = (book*)malloc(sizeof(book));//增加人员链表节点
printf("输入你的名字: ");
scanf("%s",str1);
printf("输入你的×××:");
scanf("%s",str2);
printf("输入你要的买的数量:");
scanf("%d",&dnum);/*买票的数量*/
if(dnum > r[t]->data.ticketnum){
printf("你所需要的票数过多,无法购买!!!");
return;
}
r[t]->data.ticketnum = r[t]->data.ticketnum-dnum;//定票成功则票数相应减少
/*对人员信息表添加节点,q= h 表示在尾部添加*/
h->data.bookNum = dnum;
strcpy(h->data.name,str1);
strcpy(h->data.num,str2);
h->next = NULL;
q->next = h;
q = h;
printf("\n恭喜购票成功!!!\n");
saveflag = 1;
}
else{
printf("输入有误");
return;
}
}
}
}
void SaveTrainInfo(Link l)
{
FILE *fp;//申明一个文件指针
Node *p;//申明一个火车的节点
int count = 0 , flag = 1;
fp = fopen("g:/train.txt","wb");
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;
}
}
if(flag){//如果写入成功
printf("保存%d列火车记录\n",count);
saveflag = 0;
}else{
printf("保存文件失败");
}
fclose(fp);
}
/*保存订票人的信息*/
void SaveBookInfo(bookLink k)
{
FILE *fp;//申明一个文件指针
book *p;//申明一个火车的节点
int count = 0 , flag = 1;
fp = fopen("g:/man.txt","wb");
if(fp == NULL)
{
printf("无法打开该文件");
return ;
}
p = k->next;
while(p)
{
if(fwrite(p,sizeof(book),1,fp) == 1){//每次写入一个结构进去
p = p->next;
count++;
}else
{
flag = 0;
break;
}
}
if(flag){//如果写入成功
printf("保存%d列人员记录\n",count);
saveflag = 0;
}else{
printf("保存文件失败");
}
fclose(fp);
}
int main(){
FILE *fp1,*fp2;//fp1文件指针对应火车信息,fp2文件指针对应人员信息
Node *p,*r; //表示火车信息节点 p用来表示读文件的节点
char ch2,ch3;
Link l; //表示火车信息的链表 l指的是链表的首位
bookLink k; //这里表示人员的链表
book *t,*h; //表示人员的节点
int sel; //选择菜单变量
l = (Node*)malloc(sizeof(Node));
l->next = NULL; //它下一个节点指向NULL
r = l; //利用r来做一个循环表示
k = (book*)malloc(sizeof(book));
k->next = NULL; //它下一个节点指向NULL
h = k;
/*火车基本信息的读取*/
fp1 = fopen("g:/train.txt","ab+"); //打开存储火车信息的文件(如果没有该文件就写一个)
if(fp1 == NULL){
printf("无法打开该文件");
return 0;
}
while(!feof(fp1)){ //feof()函数表示读文件到了文件的结尾( EOF表示文件的结尾)
p = (Node*)malloc(sizeof(Node));
if(fread(p,sizeof(Node),1,fp1) == 1)/*从指定磁盘文件读取记录*/
{
p->next = NULL; //因为p为节点,p后面现在还有指向,给它初始化
r->next = p; //构建链表
r = p;
}
}
fclose(fp1);
/*人员基本操作的读取*/
fp2 = fopen("g:/man.txt","ab+");
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);
while(1){
menu();
printf("\t请选择(0~6):");
scanf("%d",&sel);
system("cls");
if(sel == 0)
{
if(saveflag == 1)//表示未保存
{
getchar();
printf("\n该文件已更改!你想保存它么(y/n)?\n");
scanf("%c",&ch2);
if(ch2 == 'y' || ch2 == 'Y'){
/*保存
1、火车信息文件
2、人员操作文件
*/
SaveTrainInfo( l);
SaveBookInfo(k);
}
}
printf("\n谢谢使用 下次光临\n");
break;
}
switch(sel)/*根据与输入的sel值不同选择相对应的操作*/
{
case 1:
Trianinfo(l);/*插入火车信息*/
break;
case 2:
searchtrian(l);/*搜索火车信息*/
break;
case 3:
Bookticket(l,k);/*预定火车票 */
break;
case 4:
Modify(l);/*修改火车信息*/
break;
case 5:
showtrain(l);/*显示火车信息*/
break;
case 6:
/*保存
1、火车信息文件
2、人员操作文件
*/
SaveTrainInfo(l);
SaveBookInfo(k);
break;
case 0:
return 0;
}
printf("\n请按任意键继续...");
}
system("pause");
return 0;
}