**飞机订票系统**
一、资料来源
CSDN博主吴朋奉阅读量最高的一篇博文--飞机订票系统(C语言)----https://blog.csdn.net/weixin_47774641/article/details/111398063?spm=1001.2014.3001.5506
二、运行环境
Windows 11 + DEVC++
三、源代码(来自博主吴朋奉)
点击查看代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define M 9999
struct flight // 航班
{
char fliname[10]; // 航班号
char sp[36]; // 起飞地点
char de[36]; // 目的地
int num1; // 座位数
int num2; // 已订出票数
};
struct book // 预定
{
char fliname[10]; // 航班号
char na[50]; // 姓名
char id[19]; // 身份证号(至多18位数)
char ph[30]; // 手机号
int st; // 状态(1表示已经预约,0则表示已经退订)
};
FILE * fp1;
FILE * fp2;
int count1 = 0;
int count2 = 0;
struct flight A[M];
struct book B[M];
void init() // 初始化
{
fp1 = fopen("flightfile.txt", "r");
if(fp1 == NULL)
printf("can't open the flightfile! \n");
else
{
// 将文件指针移动到文件开头
fseek(fp1, 0, SEEK_SET);
// 从文件flightfile.txt中格式化读取数据
while(fscanf(fp1, "%s %s %s %d %d", A[count1].fliname, A[count1].sp, A[count1].de, &A[count1].num1, &A[count1].num2) == 5) count1 ++ ;
}
fclose(fp1);
fp2= fopen("bookfile.txt", "r");
if(fp2 == NULL)
printf("can't open the bookfile! \n");
else
{
// 将文件指针移动到文件开头
fseek(fp2, 0, SEEK_SET);
// 从文件bookfile.txt中格式化读取数据
while(fscanf(fp2, "%s %s %s %s %d", B[count2].fliname, B[count2].na, B[count2].id, B[count2].ph, &B[count2].st) == 5) count2 ++ ;
}
fclose(fp2);
}
void menu() // 菜单
{
printf("请输入你的选择:\n");
printf("1.输入航班信息\n");
printf("2.输出航班信息\n");
printf("3.查找航班信息\n");
printf("4.订票预约\n");
printf("5.退订\n");
printf("6.订票信息查询\n");
printf("7.退出系统\n\n");
}
void save1() // 保存1(向flightfile.txt中保存)
{
int i;
fp1 = fopen("flightfile.txt", "w+");
fseek(fp1, 0, SEEK_SET); // 将文件指针移动到文件开头
for(i=0; i<count1; i++) // 将数据格式化输出到文件flightfile.txt中
fprintf(fp1, "%s %s %s %d %d\n", A[i].fliname, A[i].sp, A[i].de, A[i].num1, A[i].num2);
fclose(fp1);
}
void save2() // 保存2(向bookfile.txt中保存)
{
int i;
fp2 = fopen("bookfile.txt", "w+");
fseek(fp2, 0, SEEK_SET); // 将文件指针移动到文件开头
for(i=0; i<count2; i++) // 将数据格式化输出到文件bookfile.txt中
fprintf(fp2, "%s %s %s %s %d\n", B[i].fliname, B[i].na, B[i].id, B[i].ph, B[i].st);
fclose(fp2);
}
void input() // 输入航班信息
{
int i,flag=1;
printf("请输入航班号:");
scanf("%s", A[count1].fliname);
for(i=0; i<count1; i++) // 判定航班号是否已经存在!
if(strcmp(A[count1].fliname, A[i].fliname) == 0)
{
printf("该航班号已存在,请重新选择输入航班信息并输入!\n\n");
flag = 0;
break;
}
if(flag == 1)
{
printf("起飞地点:");
scanf("%s", A[count1].sp);
printf("目的地:");
scanf("%s", A[count1].de);
printf("座位数:");
scanf("%d", &A[count1].num1);
printf("已订出票数:");
scanf("%d", &A[count1].num2);
printf("\n");
count1 ++ ;
save1();
}
}
void show() // 输出航班信息
{
int i;
printf("航班号\t起飞地点\t目的地\t剩余座位数\n");
for(i=0; i<count1; i++)
{
printf("%s\t%s \t%s \t%d\n", A[i].fliname, A[i].sp, A[i].de, A[i].num1-A[i].num2);
}
printf("\n");
}
void find() // 查找航班信息(按线路查询)
{
int i, num=0, flag=1;
char sp[36];
char de[36];
printf("请输入起飞地点:");
scanf("%s", sp);
printf("请输入目的地:");
scanf("%s", de);
printf("航班号\t起飞地点\t目的地\t剩余座位数\n");
for(i=0; i<count1; i++)
{
if(strcmp(sp, A[i].sp)==0 && strcmp(de, A[i].de)==0) // 按照用户输入的起飞地点和目的地到结构体flight数组A中查找相应的航班
{
printf("%s\t%s \t%s \t%d\n", A[i].fliname, A[i].sp, A[i].de, A[i].num1-A[i].num2);
num ++ ;
flag = 0;
}
}
if(flag == 1)
{
printf("无 %s %s 0\n", sp, de);
}
printf("本次共计为您查询到%d次航班!\n\n", num);
}
void booking() // 订票预约
{
int i, flag = 0;
printf("请输入航班号:");
scanf("%s", B[count2].fliname);
for(i=0; i<count1; i++)
if( strcmp(B[count2].fliname, A[i].fliname)==0 && A[i].num1-A[i].num2>0 )
{
flag = 1;
break;
}
if(flag == 1)
{
int j = -1;
printf("姓名:");
scanf("%s", B[count2].na);
printf("身份证号:");
scanf("%s", B[count2].id);
printf("手机号:");
scanf("%s", B[count2].ph);
printf("请您确认输入的信息:\n航班号:%s\n姓名:%s\n身份证号:%s\n手机号:%s\n", B[count2].fliname, B[count2].na, B[count2].id, B[count2].ph);
printf("输入数字1确认预约该航班,输入数字2重新选择订票预约:");
scanf("%d", &j);
if(j == 1)
{
B[count2].st=1;
count2 ++ ;
A[i].num2 ++ ; // 预约成功后相应的航班的已订出票数++
save2();
save1();
printf("您已成功预约航班号为%s从%s出发到达%s的航班!祝您旅途愉快!\n\n", B[count2-1].fliname, A[i].sp,A[i].de);
}
else
printf("请您重新选择订票预约!\n\n");
}
else
printf("该航班不存在或是该航班已无可预约座位,请重新选择订票预约并输入存在的航班号!\n\n");
}
void unsubscribe() // 退订
{
int i, flag=0;
char fliname[10]; // 航班号
char na[50]; // 姓名
char id[19]; // 身份证号
char ph[30]; // 手机号
int st; // 状态(1表示已经预约,0则表示已经退订)
printf("请输入航班号:");
scanf("%s", fliname);
printf("姓名:");
scanf("%s", na);
printf("身份证号:");
scanf("%s", id);
printf("手机号:");
scanf("%s", ph);
for(i=0; i<count2; i++)
if( strcmp(fliname, B[i].fliname)==0 && strcmp(na, B[i].na)==0 && strcmp(id, B[i].id)==0 && strcmp(ph, B[i].ph)==0 )
{
flag = B[i].st;
break;
}
if(flag == 1)
{
printf("请输入数字0确认退订该航班:");
scanf("%d", &B[i].st);
while(B[i].st != 0)
{
printf("请输入数字0确认退订该航班:");
scanf("%d",&B[i].st);
}
save2();
for(i=0; i<count1; i++)
if(strcmp(fliname, A[i].fliname) == 0)
break;
A[i].num2 -- ; // 退订成功后相应的航班的已订出票数--
save1();
printf("您已成功退订航班号为%s从%s出发到达%s的航班!\n\n", fliname,A[i].sp, A[i].de);
}
else
printf("该航班未被您预约,请重新选择退订并输入您已预约的航班号!\n\n");
}
void information() // 订票信息查询
{
int i,j,flag = 1;
char fliname[10]; // 航班号
char na[50]; // 姓名
char id[19]; // 身份证号
char ph[30]; // 手机号
printf("航班号:");
scanf("%s", fliname);
printf("姓名:");
scanf("%s", na);
printf("身份证号:");
scanf("%s", id);
printf("手机号:");
scanf("%s", ph);
for(i=0; i<count2; i++)
if(strcmp(fliname, B[i].fliname)==0 && strcmp(na, B[i].na)==0 && strcmp(id, B[i].id)==0 && strcmp(ph, B[i].ph)==0 && B[i].st==1)
{
flag = 0;
for(j=0; j<count1; j++)
if(strcmp(fliname, A[j].fliname)==0)
{
printf("订票信息查询成功,信息如下:\n");
printf("航班号\t起飞地点\t目的地\n");
printf("%s\t%s\t %s\n\n", A[j].fliname, A[j].sp, A[j].de);
break;
}
break;
}
if(flag) printf("未查询到您的航班,请重新输入信息查询!\n\n");
}
int main()
{
init(); // 初始化
int choice;
while(1)
{
menu(); // 菜单
scanf("%d", &choice);
switch(choice)
{
case 1: input(); break; // 输入航班信息
case 2: show(); break; // 输出航班信息
case 3: find(); break; // 查找航班信息
case 4: booking(); break; // 订票预约
case 5: unsubscribe(); break; // 退订
case 6: information(); break; // 订票信息查询
case 7: exit(0); break; // 退出系统
}
}
return 0;
}
四、源代码运行截图
五、思考与见解
1、结构体设计小问题:个人认为飞机航班信息必不可少的除了博主设置的这几项之外,预定机票的用户一定要知道的是飞机起降时间和票价;
解决:在航班结构体中加上起飞时间st、降落时间et和票价price,将相应的文件输入、输出也做相应的改变;
2、(增加功能)修改航班信息:航班信息的改动是不可避免的,因此决定添加此功能。
3、(增加功能)删除航班信息:飞机的飞行是由很多因素决定的,例如,天气情况对飞行也有着决定性的作用,因此,航空人员会修改航班飞行时间,或者直接暂停此飞行路线。
4、(增加功能)修改订票信息:从用户的角度考虑,预定机票(抢票)是在很快速的时间段内完成的,一般抢票成功之后都需要查看一下自己的订单,用户因此也无法很确切地知道自己地订票信息是否是正确的,为了保证用户自己出行便利,如有差错,可使用此功能修改自己地订票信息。
六、改动后的代码(对原来的代码大部分都有改动,所以全部代码都被附上)
点击查看代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define M 9999
struct flight // 航班
{
int fliname; // 航班号
char sp[36]; // 起飞地点
char de[36]; // 目的地
int num1; // 座位数
int num2; // 已订出票数
char st[10]; //起飞时间
char et[10]; //降落时间
int price; //票价
};
struct book // 预定
{
int fliname; // 航班号
char na[50]; // 姓名
char id[19]; // 身份证号(至多18位数)
char ph[30]; // 手机号
int st; // 状态(1表示已经预约,0则表示已经退订)
};
FILE * fp1;
FILE * fp2;
int count1 = 0;
int count2 = 0;
struct flight A[M];
struct book B[M];
void init() // 初始化
{
fp1 = fopen("flightfile.txt", "r");
if(fp1 == NULL)
printf("can't open the flightfile! \n");
else
{
// 将文件指针移动到文件开头
fseek(fp1, 0, SEEK_SET);
// 从文件flightfile.txt中格式化读取数据
while(fscanf(fp1, "%d %s %s %d %d %s %s %d", A[count1].fliname, A[count1].sp, A[count1].de, &A[count1].num1, &A[count1].num2, A[count1].st, A[count1].et, &A[count1].price) == 8) count1 ++ ;
}
fclose(fp1);
fp2= fopen("bookfile.txt", "r");
if(fp2 == NULL)
printf("can't open the bookfile! \n");
else
{
// 将文件指针移动到文件开头
fseek(fp2, 0, SEEK_SET);
// 从文件bookfile.txt中格式化读取数据
while(fscanf(fp2, "%d %s %s %s %d", B[count2].fliname, B[count2].na, B[count2].id, B[count2].ph, &B[count2].st) == 5) count2 ++ ;
}
fclose(fp2);
}
void menu() // 菜单
{
printf("请输入你的选择:\n");
printf("1.输入航班信息\n");
printf("2.输出航班信息\n");
printf("3.查找航班信息\n");
printf("4.订票预约\n");
printf("5.退订\n");
printf("6.订票信息查询\n");
printf("7.删除飞机信息\n");
printf("8.退出\n");
}
void save1() // 保存1(向flightfile.txt中保存)
{
int i;
fp1 = fopen("flightfile.txt", "w+");
fseek(fp1, 0, SEEK_SET); // 将文件指针移动到文件开头
for(i=0; i<count1; i++) // 将数据格式化输出到文件flightfile.txt中
fprintf(fp1, "%d %s %s %d %d %s %s %d\n", &A[i].fliname, A[i].sp, A[i].de, A[i].num1, A[i].num2, &A[i].st, &A[i].et, &A[i].price);
fclose(fp1);
}
void save2() // 保存2(向bookfile.txt中保存)
{
int i;
fp2 = fopen("bookfile.txt", "w+");
fseek(fp2, 0, SEEK_SET); // 将文件指针移动到文件开头
for(i=0; i<count2; i++) // 将数据格式化输出到文件bookfile.txt中
fprintf(fp2, "%d %s %s %s %d\n", B[i].fliname, B[i].na, B[i].id, B[i].ph, B[i].st);
fclose(fp2);
}
void input() // 输入航班信息
{
int i,flag=1;
printf("请输入航班号:");
scanf("%d", A[count1].fliname);
for(i=0; i<count1; i++) // 判定航班号是否已经存在!
if(A[count1].fliname==A[i].fliname)
{
printf("该航班号已存在,请重新选择输入航班信息并输入!\n\n");
flag = 0;
break;
}
if(flag == 1)
{
printf("起飞地点:");
scanf("%s", A[count1].sp);
printf("目的地:");
scanf("%s", A[count1].de);
printf("座位数:");
scanf("%d", &A[count1].num1);
printf("已订出票数:");
scanf("%d", &A[count1].num2);
printf("起飞时间:");
scanf("%s", A[count1].st);
printf("落地时间:");
scanf("%s", A[count1].et);
printf("票价:");
scanf("%d", &A[count1].price);
printf("\n");
count1 ++ ;
save1();
}
}
void show() // 输出航班信息
{
int i;
for(i=0; i<count1; i++)
{
printf("航班号:%s 起飞时间:%s 目的地:%s 剩余座位数:%d 起飞时间:%s 降落时间:%s 票价:%d\n", A[i].fliname, A[i].sp, A[i].de, A[i].num1-A[i].num2,A[i].st,A[i].et,A[i].price);
}
printf("\n");
}
void find() // 查找航班信息(按线路查询)
{
int i, num=0, flag=1;
char sp[36];
char de[36];
printf("请输入起飞地点:");
scanf("%s", sp);
printf("请输入目的地:");
scanf("%s", de);
//printf("航班号\t起飞地点\t目的地\t剩余座位数\t起飞时间\t落地时间\t票价\n");
for(i=0; i<count1; i++)
{
if(strcmp(sp, A[i].sp)==0 && strcmp(de, A[i].de)==0) // 按照用户输入的起飞地点和目的地到结构体flight数组A中查找相应的航班
{
printf("航班号:%s 起飞地点:%s 目的地:%s 剩余座位数:%d 起飞时间:%s 落地时间:%s 票价:%d\n", A[i].fliname, A[i].sp, A[i].de, A[i].num1-A[i].num2,A[i].st,A[i].et,A[i].price);
num ++ ;
flag = 0;
}
}
if(flag == 1)
{
printf("无 %s %s 0\n", sp, de);
}
printf("本次共计为您查询到%d次航班!\n\n", num);
}
void booking() // 订票预约
{
int i, flag = 0;
printf("请输入航班号:");
scanf("%s", B[count2].fliname);
for(i=0; i<count1; i++)
if( (B[count2].fliname==A[i].fliname) && A[i].num1-A[i].num2>0 )
{
flag = 1;
break;
}
if(flag == 1)
{
int j = -1;
printf("姓名:");
scanf("%s", B[count2].na);
printf("身份证号:");
scanf("%s", B[count2].id);
printf("手机号:");
scanf("%s", B[count2].ph);
printf("请您确认输入的信息:\n航班号:%s\n姓名:%s\n身份证号:%s\n手机号:%s\n", B[count2].fliname, B[count2].na, B[count2].id, B[count2].ph);
printf("输入数字1确认预约该航班,输入数字2重新选择订票预约:");
scanf("%d", &j);
if(j == 1)
{
B[count2].st=1;
count2 ++ ;
A[i].num2 ++ ; // 预约成功后相应的航班的已订出票数++
save2();
save1();
printf("您已成功预约航班号为%s从%s出发到达%s的航班!祝您旅途愉快!\n\n", B[count2-1].fliname, A[i].sp,A[i].de);
}
else
printf("请您重新选择订票预约!\n\n");
}
else
printf("该航班不存在或是该航班已无可预约座位,请重新选择订票预约并输入存在的航班号!\n\n");
}
void unsubscribe() // 退订
{
int i, flag=0;
int fliname; // 航班号
char na[50]; // 姓名
char id[19]; // 身份证号
char ph[30]; // 手机号
int st; // 状态(1表示已经预约,0则表示已经退订)
printf("请输入航班号:");
scanf("%d", fliname);
printf("姓名:");
scanf("%s", na);
printf("身份证号:");
scanf("%s", id);
printf("手机号:");
scanf("%s", ph);
for(i=0; i<count2; i++)
{
if (fliname==B[i].fliname)
{
if(strcmp(na, B[i].na)==0 && strcmp(id, B[i].id)==0 && strcmp(ph, B[i].ph)==0 )
{
flag = B[i].st;
break;
}
}
}
if(flag == 1)
{
printf("请输入数字0确认退订该航班:");
scanf("%d", &B[i].st);
while(B[i].st != 0)
{
printf("请输入数字0确认退订该航班:");
scanf("%d",&B[i].st);
}
save2();
for(i=0; i<count1; i++)
if(fliname==A[i].fliname)
break;
A[i].num2 -- ; // 退订成功后相应的航班的已订出票数--
save1();
printf("您已成功退订航班号为%d从%s出发到达%s的航班!\n\n", fliname,A[i].sp, A[i].de);
}
else
printf("该航班未被您预约,请重新选择退订并输入您已预约的航班号!\n\n");
}
void information() // 订票信息查询
{
int i,j,flag = 1;
int fliname; // 航班号
char na[50]; // 姓名
char id[19]; // 身份证号
char ph[30]; // 手机号
printf("航班号:");
scanf("%d", fliname);
printf("姓名:");
scanf("%s", na);
printf("身份证号:");
scanf("%s", id);
printf("手机号:");
scanf("%s", ph);
for(i=0; i<count2; i++)
{
if(fliname==B[i].fliname)
{
if(strcmp(na, B[i].na)==0 && strcmp(id, B[i].id)==0 && strcmp(ph, B[i].ph)==0 )
{
if(B[i].st==1)
{
flag = 0;
for(j=0; j<count1; j++)
if(fliname==A[j].fliname)
{
printf("订票信息查询成功,信息如下:\n");
printf("航班号\t起飞地点\t目的地\n");
printf("%d\t%s\t %s\n\n", A[j].fliname, A[j].sp, A[j].de);
break;
}
break;
}
}
}
}
if(flag) printf("未查询到您的航班,请重新输入信息查询!\n\n");
}
void deleteflight() //删除模块
{
int fliname; // 航班号
char sp[36]; // 起飞地点
char de[36]; // 目的地
int num1; // 座位数
//int num2; // 已订出票数
char st[10]; //起飞时间
//char et[10]; //降落时间
int price; //票价
char sp1[20];
char de1[20];
char sysm[]="jim007";
char youm[20];
int i,w,p,q,k=0;
printf("请输入密码: ");
scanf("%s",youm) ;
if(strcmp(sysm,youm)!=0)
{
printf("输入密码错误!请确认您是否是票务人员,如不是,请按任意键返回菜单重新选择" );
getchar();
//getchar();
//home();
}
else
printf("1.按航班号删除 \n");
printf("2.按航线删除 \n");
printf("请在1-2中选择删除方式: ");
scanf("%d",&q);
switch(q)
{
case 1:
printf("请输入航班号: ");
scanf("%d",&p);
break;
case 2:
printf("请输入起飞地点: ");
scanf("%s",&sp);
printf("请输入降落地点: ");
scanf("%s",&de);
break;
}
printf("\n\n航班号\t起飞地点\t降落地点\t起飞时间\t票价\t机票数 \n\n");
for(i=0;i<=2;i++)
{
if(q==1&&A[i].fliname==p)
{
k++;
printf("\n\n%d\t%s\t%s\t%s\t%lf\t%d\n",A[i].fliname,A[i].sp,A[i].de,A[i].st,A[i].price,A[i].num1);
}
if(q==2&&strcmp(A[i].sp,sp1)==0&&strcmp(A[i].de,de1)==0)
{
k++;
printf("\n\n%d\t%s\t%s\t%s\t%lf\t%d\n",A[i].fliname,A[i].sp,A[i].de,A[i].st,A[i].price,A[i].num1);
}
}
if(k=0)
printf("没有找到此航班,无法删除!");
else
printf("确定删除请按 1 否则请按 0:\n\n");
scanf("%d",&w);
if(w==1)
for(i=0;i<=k;i++)
{
A[i].fliname=0;
strcpy(A[i].sp,"0");
strcpy(A[i].de,"0");
strcpy(A[i].st,"0");
A[i].price=0;
A[i].num1=0;
}
getchar();
//getchar();
//home();
}
int main()
{
init(); // 初始化
int choice;
while(1)
{
menu(); // 菜单
scanf("%d", &choice);
switch(choice)
{
case 1: input(); break; // 输入航班信息
case 2: show(); break; // 输出航班信息
case 3: find(); break; // 查找航班信息
case 4: booking(); break; // 订票预约
case 5: unsubscribe(); break; // 退订
case 6: information(); break; // 订票信息查询
case 7: deleteflight();break; // 退出系统
case 8: exit(0); break;
}
return 0;
}
}
七、测试截图
八、总结反思
1、首先是此次逆向软件工程学习的不足之处,没有做出来修改飞机订票系统的修改航空信息这一项,原因是:原作者的所有代码里没有使用指针,这使得修改这一操作编写起来有难度,没有做出来,就先编写出了删除飞机信息的功能,这功能在一定程度上弥补了修改信息的功能,如需要修改航班信息,可先直接删除,再重新录入;
2、逆向软件工程的优缺点:优点是不用从0开始完成系统的编写,看到初步形成的代码,利于自己着力于思考提升的空间;缺点是每个代码编写者的思路和标识方式都是不同的,还是需要花费时间去整理出整个源代码的思路;
3、就我个人而言,目前来说,最难的点是编写代码这部分,需要多加练习;就这次的自己整改,虽然添加的新功能不多,但是由于添加了新的结构体元素进去,需要改动的地方较多,加上后续添加的删除功能,调试花费了最长的时间,总结来说,我的代码编写能力需得努力提高。