源码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define FALSE -1
#define TRUE 1
//航班日期枚举类,星期一到星期天
enum Week {
Mon = 1, Tues,Wed,Thurs,Fri,Sat,Sun
};
//乘客节点
typedef struct CustomerNode {
char name[10];//客户姓名
int clientTickets;//客户订票量
char identification[20];//客户身份证号码
CustomerNode *next;
} CustomerNode, *CusLinkList;
//航班节点
typedef struct Flight {
char startPoint[20];//起点站名
char destination[20];//终点站名
char flightCodeID[20];//航班ID
char planeNum[20];//飞机号
char day[20];//飞行日期(星期几)
int totalTickets;//乘员定额(总票数)
int left;//总余票量
Flight *next;
CusLinkList cusLinkList;//乘员名单域,指向乘员名单链表的头指针
} Flight, FlightNode, *PFlight;
//查询航班信息
Flight *find();
//初始化已订票乘客指针链表。param cusLinkList 航班中乘员链表的头指针
int InitCusLinkList(CusLinkList &cusLinkList);
//打印航班信息
void Display(struct Flight *info);
//增加航班时输入日期的函数(1代表星期一,7代表星期日)
int IputDay(int day1, char day[]);
//根据输入的终点站名输出航线信息
void SearchFlight();
//打印订票乘员名单域的客户名单信息(不包括身份证)
void PriCusInfo();
//订票功能模块
void BookTickets();
//退票功能模块
void ReturnTicket();
//搜索界面
void Search();
//订票界面
void Bookticket();
//退票界面
void ReturnTickets();
//退出程序模块
void GoodbyeFace();
//打印全部航班信息,flight 传入的是航班链表的头指针
void PrintFilghtlist(Flight *flight);
//菜单界面
int MenuSelect();
//管理员界面
void AdministratorFace();
//根据客户提出的起点,终点站名输出航线信息
void SearchFlight();
//推荐订票,startPoint起点, destination终点, flight原航班,用来辅助选出同一路线但不同航班ID的航班
void Suggest(char startPoint[], char destination[], Flight *flight);
//将flight1的航班用头插入法插入到pFlight的链表中, flight1 里面存有六个基本航班
int Create(PFlight flight1);
// 管理员插入航班时遍历航班,防止航班ID重复(航班ID相当于主键)
int TraverseFlight(Flight *flight, char flightCodeID[]);
//定义全局指针变量pFlight,航班链表的头指针
Flight *pFlight;
//六个基本航班
Flight flight1[7] = {
{"广州", "北京", "1", "B3333", "星期一", 10,10},
{"广州", "北京", "2", "D5555", "星期二", 8,8},
{"广州", "北京", "3", "L6666", "星期天", 10,10},
{"上海", "广州", "4", "K9999", "星期三", 8,8},
{"广州", "成都", "5", "K7777", "星期三", 10,10},
{"成都", "广州", "6", "K8888", "星期三", 8,8}
};
/**
* 初始化航班链表
* 目的是要初始化移pFlight为头结点的空航班链表,录入航班信息和增加航班后将航班结点插入该链表
*/
void InitFlight() {
pFlight = (Flight *) malloc(sizeof(Flight));//申请头结点的空间
if (pFlight == NULL) exit(0);
pFlight->next = NULL;//将头结点h的指针域置为空
}
/**
* 将flight1的航班用头插入法插入到pFlight的链表中
* flight1 里面存有六个基本航班
* 返回操作是否成功
*/
int Create(PFlight flight1) {
Flight *p = pFlight, *q;
for (int i; i < 6; i++) {
q = (Flight *) malloc(sizeof(Flight));
if (q == NULL)
return ERROR;
strcpy(q->startPoint, flight1[i].startPoint);
strcpy(q->destination, flight1[i].destination);
strcpy(q->flightCodeID, flight1[i].flightCodeID);
strcpy(q->planeNum, flight1[i].planeNum);
strcpy(q->day, flight1[i].day);
q->totalTickets = flight1[i].totalTickets;
q->left = flight1[i].left;
//初始化乘客链表
InitCusLinkList(q->cusLinkList);
q->next = p->next;
p->next = q;
}
return OK;
}
void save(Flight *f){
FILE *p;
p=fopen("航班信息.txt","w+");
if(p==NULL){
printf("未保存文件!!!");
}
Flight *info=f->next;
while(info!=NULL){
fprintf(p,"%8s\t%8s\t%3s\t%s\t%4s\t\t%3d\t%10d\n", info->startPoint, info->destination, info->flightCodeID,
info->planeNum, info->day,
info->totalTickets, info->left);
info=info->next;
}
printf("保存成功!!!");
fclose(p);
}
/**
* 管理员操作
* 将新的航班结点插入到航班链表中,
* 采用头插入法
* 返回操作是否成功
*/
int InsertFlight() {
FlightNode *q;//定义q为新增加的航班结点的指针的形参
Flight *p = pFlight;
int flag = 1;
while (flag != 0) {
q = (FlightNode *) malloc(sizeof(FlightNode));
if (q == NULL)
return ERROR;
printf("\t\t请依次输入以下内容\n");
printf("\t\t请输入航班ID\n");
scanf("%s", q->flightCodeID);
int a = TraverseFlight(pFlight, q->flightCodeID);
if (a == ERROR) {
printf("该航班ID已经存在,请重新输入航班ID\n");
continue;
}
printf("\t\t请输入起点站名\n");
scanf("%s", q->startPoint);
printf("\t\t请输入终点站名\n");
scanf("%s", q->destination);
printf("\t\t请输入飞机号\n");
scanf("%s", q->planeNum);
printf("\t\t请输入飞行日期(1代表星期,2代表星期二.....7代表星期日)\n");
int day1;
scanf("%d", &day1);
while (ERROR == IputDay(day1, q->day)) {
printf("请输入合法数据(1-7)\n");
scanf("%d", &day1);
};
printf("\t\t请输入乘客定额\n");
scanf("%d", &q->totalTickets);
q->left = q->totalTickets;
q->next = p->next;
p->next = q;
printf("\t\t是否继续录入航班信息(任意数字继续,0表示停止)\n");
printf("\t\t请输入:");
scanf("%d", &flag);
}
return OK;
}
/**
* 管理员操作
* 删除节点
* 返回操作是否成功
*/
int DeleteFlight() {
char flightCodeID[20];
printf("请输入航班ID\n");
scanf("%s", flightCodeID);
PFlight pre = pFlight;
PFlight p = pre->next;
while (p != NULL) {
if (!strcmp(flightCodeID, p->flightCodeID)) {
pre->next = p->next;
free(p);
return OK;
}
pre = p;
p = p->next;
}
return ERROR;
}
/**
* 验证管理员密码
* 返回操作结果
*/
int Administrator() {
char pwd[20] = "12345";//管理员密码
char password[20];//待输入密码,用来验证
printf("请输入管理员密码:\n");
scanf("%s", password);
if (strcmp(pwd, password)) {
printf("密码错误,请重新输入:\n");
return FALSE;
}
printf("验证成功\n");
return TRUE;
}
/**
* 管理员的查询操作
* 打印订票乘员名单域的客户名单信息
*/
void AdminPriCusInfo() {
CusLinkList p;
Flight *info;
info = find();
if (info == NULL) {
printf("没有这个航班\n");
return;
}
//头结点的下一个节点开始遍历
p = info->cusLinkList->next;
if (p != NULL) {
printf("客户姓名 订票数额 身份证号码\n");
while (p) {
printf("%s\t\t%d\t\t\t%s\n", p->name, p->clientTickets, p->identification);
p = p->next;
}
} else
printf("该航班没有客户信息!!\n");
}
//管理员界面
void AdministratorFace() {
int a2;
//system("cls");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf(" 欢迎来到管理员界面\n");
printf(" ------------------------------------\n");
printf(" | 1.航班信息 |\n");
printf(" | 2.客户信息 |\n");
printf(" | 3.增加航班 |\n");
printf(" | 4.删除航班 |\n");
printf(" | 5.保存航班信息 |\n");
printf(" | 6.返回上一级 |\n");
printf(" ------------------------------------|\n");
printf(" 请输入您的选择:");
scanf("%d", &a2);
switch (a2) {
case 1:
PrintFilghtlist(pFlight);
system("PAUSE");
AdministratorFace();
break;
case 2:
AdminPriCusInfo();
AdministratorFace();
case 3:
InsertFlight();
AdministratorFace();
break;
case 4:
if (OK == DeleteFlight()) {
printf("删除成功\n");
} else {
printf("没有这个航班,删除失败!\n");
};
AdministratorFace();
case 5:
save(pFlight);
case 6:
MenuSelect();
break;
default:
printf("你的输入有误!请重新输入!");
}
}
/**
* 增加航班时输入日期的辅助函数(1代表星期一,7代表星期日)
* day1 传进来的1-7中的一个
* day 数组类变量,可以返回回去给航班的日期变量
* 返回操作状态,输入是否合法
*/
int IputDay(int day1, char day[]) {
switch (day1) {
case Mon:
strcpy(day, "星期一");
break;
case Tues:
strcpy(day, "星期二");
break;
case Wed:
strcpy(day, "星期三");
break;
case Thurs:
strcpy(day, "星期四");
break;
case Fri:
strcpy(day, "星期五");
break;
case Sat:
strcpy(day, "星期六");
break;
case Sun:
strcpy(day, "星期日");
break;
default:
return ERROR;
}
return OK;
}
/**
*菜单界面函数
*返回选择的操作
*/
int MenuSelect() {
int select;
int a;
system("cls");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf(" 欢迎使用航空订票系统\n");
printf(" ---------------------------------\n");
printf(" | 1. 查询机票 |\n");
printf(" | 2. 搜索机票 |\n");
printf(" | 3. 订票 |\n");
printf(" | 4. 退票 |\n");
printf(" | 5. 管理员界面 |\n");
printf(" | 6. 退出系统 |\n");
printf(" ---------------------------------\n");
printf(" 请输入(1-6)否则无效! 请输入您的选择:");
scanf("%d", &select);
switch (select) {
case 1:
//查询所有航班信息
//传入航班链表头指针,打印出所有航班信息
PrintFilghtlist(pFlight);
system("PAUSE");
MenuSelect();
break;
case 2:
//进入搜索界面
Search();
system("PAUSE");
MenuSelect();
break;
case 3:
//进入订票界面
Bookticket();
system("PAUSE");
MenuSelect();
break;
case 4:
//进入退票界面
ReturnTickets();
system("PAUSE");
MenuSelect();
break;
case 5:
//进入管理员界面
while (1) {
a = Administrator();
if (TRUE == a)
break;
}
AdministratorFace();
system("PAUSE");
MenuSelect();
break;
case 6:
//退出系统
GoodbyeFace();
break;
default:
printf("你的输入有误!");
}
}
//打印info航班的基本信息
void Display(Flight *info) {
printf("%8s\t%8s\t%3s\t%s\t%4s\t\t%3d\t%10d\n", info->startPoint, info->destination, info->flightCodeID,
info->planeNum, info->day,
info->totalTickets, info->left);
}
/**
* 查询模块
* 打印全部航班信息
* pflight 传入的是航班链表的头指针
*/
void PrintFilghtlist(Flight *pflight) {
Flight *p;
//带头结点的头指针,所以从下一个指针还是遍历
p = pflight->next;
system("cls");
printf("起点站名\t终点站名\t航班ID\t飞机号\t飞行日期\t乘员定额\t余票量\n");
while (p != NULL) {
//调用Display函数打印出每个航班节点的信息
Display(p);
p = p->next;
}
printf("\n\n");
}
//根据输入的起点,终点站名输出航线信息
void SearchFlight() {
char startPonit[10];
char destination[10];
int flag = 0;
system("cls");
printf("请输入起点站名:");
scanf("%s", startPonit);
printf("请输入终点站名:");
scanf("%s", destination);
struct Flight *p;
p = pFlight->next;
printf("起点站名\t终点站名\t航班ID\t飞机号\t飞行日期\t乘员定额\t余票量\n");
while (p != NULL) {
if ((strcmp(startPonit, p->startPoint) == 0) && (strcmp(destination, p->destination) == 0) ) {
flag = 1;
Display(p);
}
p = p->next;
}
printf("\n\n");
if (flag == 0)
printf("对不起,该航班未找到! \n");
}
//输出p节点的航班信息,p 航班节点
void FlightInfo(Flight *p) {
printf("起点站名\t终点站名\t航班ID\t飞机号\t飞行日期\t乘员定额\t余票量\n");
Display(p);
printf("\n\n");
}
/**
* 管理员插入航班时遍历航班,防止航班ID重复
* 返回是否重复
*/
int TraverseFlight(Flight *flight, char flightCodeID[]) {
Flight *p = flight;
while (p != NULL) {
//当有航班ID重复时候,返回ERROR,
if (!strcmp(flightCodeID, p->flightCodeID)) {
return ERROR;
}
p = p->next;
}
//输入的航班ID不重复
return OK;
}
/**
*根据输入的航班ID查询并以指针形式返回
* 航班指针
*/
Flight *find() {
char number[10];
printf("请输入航班ID: ");
scanf("%s", number);
//头结点的下一个节点开始遍历
Flight *p = pFlight->next;
while (p != NULL) {
if (!strcmp(number, p->flightCodeID))
return p;
p = p->next;
}
return NULL;
}
//打印订票乘员名单域的客户名单信息
void PriCusInfo() {
CusLinkList p;
Flight *info;
info = find();
if (info == NULL) {
printf("没有这个航班\n");
return;
}
//头结点的下一个节点开始遍历
p = info->cusLinkList->next;
if (p != NULL) {
printf("客户姓名 订票数额 客户身份证\n");
while (p) {
printf("%s\t\t%d\t%s\n", p->name, p->clientTickets,p->identification);
p = p->next;
}
} else
printf("该航班没有客户信息!!\n");
}
/**
* 订票成功之后,将乘客信息插入到对应航班的订成员名单域中(链表)
* head 乘客名单域头指针
* amount 该乘客订票的数量
* name 乘客的姓名
* 乘客链表头指针
*/
CusLinkList insertlink(CusLinkList &head, int amount, char name[], char identification[]) {
//成员名单域新节点new1
CusLinkList new1;
new1 = (CustomerNode *) malloc(sizeof(CustomerNode));
if (new1 == NULL) {
printf("\n内存不足\n");
return NULL;
}
//将传入乘客信息赋值给new1节点
strcpy(new1->name, name);
strcpy(new1->identification, identification);
new1->clientTickets = amount;
//头插入法加入成员名单域
new1->next = head->next;
head->next = new1;
return head;
}
//初始化已订票乘客指针链表,cusLinkList 航班中乘员链表的头指针
int InitCusLinkList(CusLinkList &cusLinkList) {
CusLinkList q = cusLinkList;
cusLinkList = (CustomerNode *) malloc(sizeof(CustomerNode));
cusLinkList->next = NULL;
}
//订票
void BookTickets() {
struct Flight *info;
int amount;
int tickets;
char name[10];
char identification[20];
system("cls");
//调用查找航班函数,返回
int loop1;
loop1:
{
info = find();
};
if (info == NULL){
printf("没有这个航班, 请重新输入\n");
goto loop1;
}
printf("请输入你订票所需要的数量:");
scanf("%d", &amount);
if (amount <= 0 ) {
printf("你的输入无效!请重新输入!");
}
if (amount <= info->left) {
int i;
printf("请输入您的姓名:");
scanf("%s", name);
printf("请输入您的身份证号码:");
scanf("%s", identification);
CusLinkList head = info->cusLinkList;
//订票成功,插入成员名单链表
insertlink(head, amount, name, identification);
for (i = 0; i < amount; i++)
printf("%s 的座位号是: %d\n", name, info->totalTickets - info->left + i + 1);
info->left -= amount;
printf("\n祝您旅途愉快!欢迎再次光临\n");
}
else
{
char r;
printf("\n是否根据建议订票?若是,则推荐相同的起点和终点的航班Y/N");
r = getch();
printf("%c", r);
printf("%c", r);
if (r == 'Y' || r == 'y') {
//调用推荐函数
Suggest(info->startPoint, info->destination, info);
} else
printf("\n欢迎您下次再次订购!\n");
}
}
//推荐
int RecommendFlight(char startPoint[], char destination[], Flight *pflight) {
//标记变量,是否找到同一路线的航班
int flag = 0;
system("cls");
struct Flight *p;
p = pFlight->next;
printf("寻找同一路线的航班\n");
printf("起点站名\t终点站名\t航班ID\t飞机号\t飞行日期\t乘员定额\t余票量\n");
while (p != NULL) {
//路线相同,且不是同一个航班,标记flag = 1,表示找到
if (strcmp(destination, p->destination) == 0 && strcmp(startPoint, p->startPoint) == 0 && p != pflight) {
flag = 1;
Display(p);
}
p = p->next;
}
printf("\n\n");
//没有相同路线的航班
if (flag == 0)
return FALSE;
return TRUE;
}
void Suggest(char startPoint[], char destination[], Flight *flight) {
int a = RecommendFlight(startPoint, destination, flight);
if (a == FALSE)
printf("对不起,没有相同起点和终点的航班了");
else {
printf("是否符合订票要求?Y|N");
{
char r;
r = getch();
printf("%c", r);
if (r == 'Y' || r == 'y') {
BookTickets();
system("PAUSE");
} else
printf("不根据建议进行订票,现在将退回主菜单");
system("PAUSE");
MenuSelect();
}
}
}
//退票功能
void ReturnTicket() {
struct Flight *info;
//p1为遍历指针,p2为辅助指针,指向p1的前驱
CustomerNode *p1, *p2, *head;
//客户姓名
char cusname[10];
//客户身份证
char identification[20];
system("cls");
//info指针,find函数根据航班ID返回该航班节点的指针
int loop;
loop:
{
info = find();
};
if (info == NULL){
printf("没有这个航班, 请重新输入\n");
goto loop;
}
//head为该航班的的乘员名单域的头指针
head = info->cusLinkList;
//带头结点的指针,head->next 开始遍历
p1 = head->next;
printf("请输入你的姓名: ");
scanf("%s", cusname);
printf("请输入你的身份证号码: ");
scanf("%s", identification);
//根据客户姓名搜索客户是否订票
p2 = head;
while (p1 != NULL) {
if ((strcmp(cusname, p1->name) == 0) && (strcmp(identification, p1->identification) == 0)) break;
p2 = p1;
p1 = p1->next;
}
if (p1 == NULL) {
printf("对不起,你没有订过票或姓名和身份证不对应\n");
return;
} else {//退票成功
//从乘客名单域中移除该节点
p2->next = p1->next;
//加回该航班的剩余票
info->left += p1->clientTickets;
printf("%s 成功退票!\n", p1->name);
free(p1);
}
}
//搜索界面
void Search() {
int a2;
system("cls");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf(" 欢迎来到搜索界面\n");
printf(" --------------------------------------\n");
printf(" | 1.搜索航班信息 | \n");
printf(" | 2.返回上一层菜单 | \n");
printf(" -------------------------------------|\n");
printf(" 请输入您的选择:");
scanf("%d", &a2);
switch (a2) {
case 1:
SearchFlight();
system("PAUSE");
Search();
break;
case 2:
MenuSelect();
break;
default:
printf("你的输入有误!请重新输入!");
}
}
//订票界面
void Bookticket() {
int a3;
system("cls");
printf("\n");
printf("\n");
printf(" 欢迎来到订票界面\n");
printf(" --------------------------------------------------\n");
printf(" | 1.客户订票 |\n");
printf(" | 2.根据起点和终点搜索航班 |\n");
printf(" | 3.查询所有航班 |\n");
printf(" | 4.通过航班ID查询订票客户名单 |\n");
printf(" | 5.返回上一级菜单 |\n");
printf(" --------------------------------------------------\n");
printf(" 请输入您的选择:");
scanf("%d", &a3);
switch (a3) {
case 1:
//订票
BookTickets();
system("PAUSE");
Bookticket();
break;
case 2:
//输入起点和终点查询
SearchFlight();
system("PAUSE");
Bookticket();
break;
case 3:
PrintFilghtlist(pFlight);
system("PAUSE");
Bookticket();
break;
case 4:
PriCusInfo();
system("PAUSE");
Bookticket();
break;
case 5:
MenuSelect();
break;
default:
printf("你的输入有误!请从新输入!");
}
}
//退票界面
void ReturnTickets() {
int a3;
system("cls");
printf("\n");
printf("\n");
printf(" 欢迎来到退票界面\n");
printf(" -------------------------------------\n");
printf(" | 1.办理退票手续 |\n");
printf(" | 2.返回上一级菜单 |\n");
printf(" --------------------------------------\n");
printf(" 请输入您的选择:");
scanf("%d", &a3);
switch (a3) {
case 1:
ReturnTicket();
system("PAUSE");
ReturnTickets();
break;
case 2:
MenuSelect();
break;
default:
printf("你的输入有误!");
}
}
//退出程序模块
void GoodbyeFace() {
system("cls");
printf("\n");
printf("\n");
printf(" ---------------------------------------------\n");
printf(" | 感谢使用航空航班订票系统 |\n");
printf(" | 欢迎你再次使用! |\n");
printf(" | 祝你旅途愉快! |\n");
printf(" ----------------------------------------------\n");
}
//pFlight为全局变量,航班链表的头指针, 先初始化pFlight航班链表,再把flight1的航班数据插入pFlight链表
int main() {
//初始化pFlight,pFlight为全局变量。
InitFlight();
//用flight1中的数据创建初始航班链表,里面含有四个节点
Create(flight1);
//菜单函数
MenuSelect();
return 0;
}
功能图:
流程图:
包含实验报告,流程图,功能图等;
链接:
hthttps://pan.baidu.com/s/1ILpNMG8tjrp0ywKIjfru6Q
提取码:ego6