基于链表的机票订购系统(C/C++)

功能

飞机订票系统(基于链表实现)C语言版本(把printf改成cout,scnaf改成cin,malloc改为new,即为C++代码)
分管理员和顾客两种角色。
航班信息包括:航班号,起飞城市,抵达城市,起降时间,航班票价,票价折扣,总票量,剩余票量

管理员功能:
    (1)录入,可以录入航班情况
    (2)修改,修改航班信息
    (3)删除,若航班没有顾客,可以删除
    (4)查询,可查询某个航线的情况,可输入起飞抵达城市查询
               查询某个航班有哪些顾客
    (5)排序,根据航班号信息进行排序

顾客功能:
    (1)注册:录入顾客信息(用户名,密码,身份证,姓名等)
    (2)订票,可以查询航班信息,进行订票
               通过航班号查询
               通过起飞地点和抵达地点查询
    (3)退票,可退票,退票后修改相关数据
    (4)查询,查询顾客个人情况,包括订单情况

    通用功能:
    航班信息和顾客订票信息保存到文件,程序启动后自动加载文件数据。

运行截图

代码

#define _CRT_SECURE_NO_WARNINGS 1
/*********************************************************************************************
飞机订票系统(基于链表实现)C语言版本(把printf改成cout,scnaf改成cin,malloc改为new,即为C++代码)
分管理员和顾客两种角色。
航班信息包括:航班号,起飞城市,抵达城市,起降时间,航班票价,票价折扣,总票量,剩余票量

管理员功能:
	(1)录入,可以录入航班情况
	(2)修改,修改航班信息
	(3)删除,若航班没有顾客,可以删除
	(4)查询,可查询某个航线的情况,可输入起飞抵达城市查询
			   查询某个航班有哪些顾客
	(5)排序,根据航班号信息进行排序

顾客功能:
	(1)注册:录入顾客信息(用户名,密码,身份证,姓名等)
	(2)订票,可以查询航班信息,进行订票
			   通过航班号查询
			   通过起飞地点和抵达地点查询
	(3)退票,可退票,退票后修改相关数据
	(4)查询,查询顾客个人情况,包括订单情况

	通用功能:
	航班信息和顾客订票信息保存到文件,程序启动后自动加载文件数据。
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//三个数据文件
const char* filenameCus = "customers.txt";    //用户信息文件
const char* filenameFlight = "flights.txt";   //航班信息文件
const char* filenameTicks = "tickets.txt";    //售票信息文件


//定义用户信息
typedef struct _customer
{
	char username[20]; //账号
	char pwd[10];      //密码
	char name[20];     //姓名 
	char card[20];     //身份证号
	//手机号等等更多信息这里就不在写了,如有需要,可自行补充,如果补充了字段,记得同时修改读写文件的相关代码
}Customer;

//定义用户链表
typedef struct _customernode
{
	Customer customer;
	struct _customernode* next;
}CustomerNode;

CustomerNode* g_customers;  //保存所有顾客信息
CustomerNode* g_customersCurrentLogin = 0;  //保存当前登录的客户信息

//定义时间
typedef struct _timeTm
{
	int hour, min;//只精确到分钟
}DayTime;


//定义航班信息--为了简单,这里不再区分不同日期的航班,只处理同一天的航班
typedef struct _flightinfo
{
	char id[10];    //航班号
	char start[20]; //起飞城市
	char end[20];   //抵达城市
	DayTime tmStart;//起飞时间
	DayTime tmEnd;  //降落时间
	int price;      //航班票价;
	float zhk;      //票价折扣 0-1之间,如8折时,值为0.8
	int toatalNmb;  //总票量
	int leftNmb;    //剩余票量
}FlightInfo;


//定义航班链表
typedef struct _flightinfonode
{
	FlightInfo flightInfo;
	struct _flightinfonode* next;
}FlightInfoNode;

FlightInfoNode* g_flights;  //保存所有航班信息


//定义购票信息结构体
typedef struct _ticksinfo
{
	FlightInfoNode* flight; //航班信息
	CustomerNode* customer; //顾客信息
}TicksInfo;

//定义链表
typedef struct _ticksinfonode
{
	TicksInfo data;
	struct _ticksinfonode* next;
}TicksInfoNode;

TicksInfoNode* g_ticks;  //保存所有订票信息

//显示航班信息标题
void showFlghtTitle()
{
	int i = 0;
	const char* p[] = { "航班号", "起始地点", "抵达地点","起飞时间", "抵达时间", "票 价" ,"折扣", "总票量", "余票" };

	printf("%-10s %-20s %-20s %-8s %-8s %-5s %-4s %-6s %-4s\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
}
//显示单条航班信息
void showSingleFlightInfo(FlightInfoNode* p)
{
	printf("%-10s %-20s %-20s   %02d:%02d    %02d:%02d  %-5d %-.1f   %-4d   %-4d\n", p->flightInfo.id, p->flightInfo.start, p->flightInfo.end,
		p->flightInfo.tmStart.hour, p->flightInfo.tmStart.min, p->flightInfo.tmEnd.hour, p->flightInfo.tmEnd.min,
		p->flightInfo.price, p->flightInfo.zhk, p->flightInfo.toatalNmb, p->flightInfo.leftNmb);
}


//根据航班号查询航班信息
FlightInfoNode* searchFlightById(const char* id)
{
	FlightInfoNode* p = g_flights->next;
	while (p)
	{
		if (strcmp(p->flightInfo.id, id) == 0)
			return p;
		else
			p = p->next;
	}
	return 0;
}
//根据起飞地点和抵达地点查询航班信息;主功能
void searchFlightByPlace()
{
	char start[20], end[20];
	int flag = 0;
	FlightInfoNode* p;
	if (g_flights == 0 || g_flights->next == 0)
	{
		printf("目前暂无航班信息\n");
		return;
	}
	printf("请输入起飞地点:");
	scanf("%s", start);
	printf("请输入抵达地点:");
	scanf("%s", end);

	p = g_flights->next;
	while (p)
	{
		if (strcmp(p->flightInfo.start, start) == 0 && strcmp(p->flightInfo.end, end) == 0)
		{
			if (flag == 0)
			{
				flag = 1;
				showFlghtTitle();
			}
			showSingleFlightInfo(p);
		}
		p = p->next;
	}
	if (flag == 0)
		printf("未找到符合条件的航班\n");
}

//根据身份证号查询用户
CustomerNode* searchCustomerByCard(char* card)
{
	CustomerNode* p = g_customers->next;
	while (p)
	{
		if (strcmp(p->customer.card, card) == 0)
			return p;
		else
			p = p->next;
	}
	return 0;
}
//从文件中读取用户信息,用户信息单独一个文件
void ReadFileforCustomer(const char* filename)
{
	FILE* fp = 0;
	CustomerNode* p, * t;
	//创建链表头
	g_customers = (CustomerNode*)malloc(sizeof(CustomerNode));
	g_customers->next = 0;
	p = g_customers;

	//打开文件
	if ((fp = fopen(filename, "r")) == 0)
	{
		printf("%s :文件打开失败\n", filename);
		return;
	}
	//读取文件数据
	while (!feof(fp))
	{
		t = (CustomerNode*)malloc(sizeof(CustomerNode));
		t->next = 0;
		//读取数据,如果成功,插入链表
		fscanf(fp, "%s %s %s %s", t->customer.username, t->customer.pwd, t->customer.name, t->customer.card);
		if (strlen(t->customer.username) > 0)
		{
			p->next = t;
			p = t;
		}
		else
			free(t); //读取失败,则释放t的空间,因为t中没有有效数据,下一次循环会重新申请空间
	}
	fclose(fp);
	printf("%s 客户信息读取成功\n", filename);
}

//将用户信息写入文件
void WreiteFileforCustomer(const char* filename)
{
	FILE* fp = 0;
	CustomerNode* p = g_customers->next;
	fp = fopen(filename, "w");
	if (fp == 0)
	{
		printf("%s:文件打开错误\n", filename);
		return;
	}
	while (p)
	{
		fprintf(fp, "%s %s %s %s\n", p->customer.username, p->customer.pwd, p->customer.name, p->customer.card);
		p = p->next;
	}
	fclose(fp);
}


//从文件中读取航班信息,航班信息单独一个文件
void ReadFileforFlight(const char* filename)
{
	FILE* fp = 0;
	FlightInfoNode* p, * t;
	int res = 0;
	//创建链表头
	g_flights = (FlightInfoNode*)malloc(sizeof(FlightInfoNode));
	g_flights->next = 0;
	p = g_flights;

	//打开文件
	if ((fp = fopen(filename, "r")) == 0)
	{
		printf("%s :文件打开失败\n", filename);
		return;
	}
	//读取文件数据
	while (!feof(fp))
	{
		t = (FlightInfoNode*)malloc(sizeof(FlightInfoNode));
		t->next = 0;
		//读取数据,如果成功,插入链表
		fscanf(fp, "%s %s %s %d:%d %d:%d %d %f %d %d", t->flightInfo.id, t->flightInfo.start, t->flightInfo.end,
			&t->flightInfo.tmStart.hour, &t->flightInfo.tmStart.min, &t->flightInfo.tmEnd.hour, &t->flightInfo.tmEnd.min,
			&t->flightInfo.price, &t->flightInfo.zhk, &t->flightInfo.toatalNmb, &t->flightInfo.leftNmb);
		if (strlen(t->flightInfo.id) > 0 && t->flightInfo.price > 0)
		{
			p->next = t;
			p = t;
		}
		else
			free(t); //读取失败,则释放t的空间,因为t中没有有效数据,下一次循环会重新申请空间
	}
	fclose(fp);
	printf("%s 航班信息读取成功\n", filename);
}

//将航班信息写入文件
void WriteFileforFlight(const char* filename)
{
	FILE* fp;
	FlightInfoNode* p = g_flights->next;
	fp = fopen(filename, "w");
	if (fp == 0)
	{
		printf("%s:文件打开错误\n", filename);
		return;
	}
	while (p)
	{
		fprintf(fp, "%s %s %s %d:%d %d:%d %d %f %d %d\n", p->flightInfo.id, p->flightInfo.start, p->flightInfo.end,
			p->flightInfo.tmStart.hour, p->flightInfo.tmStart.min, p->flightInfo.tmEnd.hour, p->flightInfo.tmEnd.min,
			p->flightInfo.price, p->flightInfo.zhk, p->flightInfo.toatalNmb, p->flightInfo.leftNmb);
		p = p->next;
	}
	fclose(fp);
}


//从文件中读取订票信息,订票信息单独一个文件,订票信息文件中只保存航班号和顾客身份证号即可
void ReadFileforTicks(const char* filename)
{
	FILE* fp = 0;
	TicksInfoNode* p, * t;
	int res = 0;
	char id[10], card[20];
	//创建链表头
	g_ticks = (TicksInfoNode*)malloc(sizeof(TicksInfoNode));
	g_ticks->data.customer = 0;
	g_ticks->data.flight = 0;
	g_ticks->next = 0;
	p = g_ticks;
	//打开文件
	if ((fp = fopen(filename, "r")) == 0)
	{
		printf("%s :文件打开失败\n", filename);
		return;
	}
	//读取文件数据
	while (!feof(fp))
	{
		t = (TicksInfoNode*)malloc(sizeof(TicksInfoNode));
		t->next = 0;
		//读取数据,如果成功,插入链表
		res = fscanf(fp, "%s %s", id, card);
		if (res > 0 && strlen(id) > 0)
		{
			//根据航班号查找航班
			t->data.flight = searchFlightById(id);
			//根据用户身份证查找用户
			t->data.customer = searchCustomerByCard(card);
			p->next = t;
			p = t;
		}
		else
			free(t); //读取失败,则释放t的空间,因为t中没有有效数据,下一次循环会重新申请空间
	}
	fclose(fp);
	printf("%s 购票信息读取成功\n", filename);
}
//将订票信息写入文件
void WriteFileTickets(const char* filename)
{
	FILE* fp;
	TicksInfoNode* p = g_ticks->next;
	fp = fopen(filename, "w");
	if (fp == 0)
	{
		printf("%s:文件打开错误\n", filename);
		return;
	}
	while (p)
	{
		fprintf(fp, "%s %s\n", p->data.flight->flightInfo.id, p->data.customer->customer.card);
		p = p->next;
	}
	fclose(fp);
}


//从文件中读取数据
void ReadFile(const char* filenameCus, const char* filenameFlight, const char* filenameTicks)
{
	ReadFileforCustomer(filenameCus);
	ReadFileforFlight(filenameFlight);
	ReadFileforTicks(filenameTicks);
}

//管理员功能:录入航班信息
void ManagerInput()
{
	FlightInfoNode* t, * x;
	char ch;

	//这里提供两种方法保存信息,一种是头插法,及将节点插入链表的最前面,一种是尾插法
	//头插法和尾插法根据需要选择一种使用
	//头插法代码:START
	while (1)
	{
		system("cls");
		t = (FlightInfoNode*)malloc(sizeof(FlightInfoNode));
		t->next = 0;
		printf("请输入航班号:");
		//判断航班号是否已经存在
		while (1)
		{
			scanf("%s", t->flightInfo.id);
			x = searchFlightById(t->flightInfo.id);
			if (x)
				printf("该航班号已经存在,请重新输入:");
			else
				break;
		}

		printf("请输入起飞城市:"); scanf("%s", t->flightInfo.start);
		printf("请输入抵达城市:"); scanf("%s", t->flightInfo.end);
		printf("请输入起飞时间(HH:MM):"); scanf("%d:%d", &t->flightInfo.tmStart.hour, &t->flightInfo.tmStart.min);
		printf("请输入降落时间(HH:MM):"); scanf("%d:%d", &t->flightInfo.tmEnd.hour, &t->flightInfo.tmEnd.min);
		printf("请输入航班票价:"); scanf("%d", &t->flightInfo.price);
		printf("请输入票价折扣:"); scanf("%f", &t->flightInfo.zhk);
		printf("请输入总票量:"); scanf("%d", &t->flightInfo.toatalNmb);
		printf("请输入剩余票量:"); scanf("%d", &t->flightInfo.leftNmb);
		t->next = g_flights->next;
		g_flights->next = t;

		printf("添加成功。");
		rewind(stdin);  //清空输入缓存 vs2015之前的版本可以使用 fflush(stdin);
		while (1)
		{
			printf("是否继续录入(Y/N):");
			ch = getchar();
			getchar();//接收回车符
			if (ch == 'Y' || ch == 'y')
				break;
			else if (ch == 'N' || ch == 'n')
			{
				//将航班信息写入文件
				WriteFileforFlight(filenameFlight);
				return;
			}
		}
	}
	//头插法 END

	/*
	//尾插法代码:START
	//先找到链表的尾节点
	p=g_flights;
	while(p->next)
		p = p->next;
	while(1)
	{
		system("cls");
		t = (FlightInfoNode*)malloc(sizeof(FlightInfoNode));
		t->next = 0;
		printf("请输入航班号:"); scanf("%s",t->flightInfo.id);
		printf("请输入起飞城市:");scanf("%s",t->flightInfo.start);
		printf("请输入抵达城市:");scanf("%s",t->flightInfo.end);
		printf("请输入起飞时间(HH:MM):");scanf("%d:%d",&t->flightInfo.tmStart.hour,&t->flightInfo.tmStart.min);
		printf("请输入降落时间(HH:MM):");scanf("%d:%d",&t->flightInfo.tmEnd.hour,&t->flightInfo.tmEnd.min);
		printf("请输入航班票价:");scanf("%d",&t->flightInfo.price);
		printf("请输入票价折扣:");scanf("%f",&t->flightInfo.zhk);
		printf("请输入总票量:");scanf("%d",&t->flightInfo.toatalNmb);
		printf("请输入剩余票量:");scanf("%d",&t->flightInfo.leftNmb);

		p->next = t;
		p = t;

		printf("添加成功。");
		flush(stdin); //清空输入缓存
		while(1)
		{
			printf("是否继续录入(Y/N):");
			ch = getchar();
			getchar();//接收回车符
			if(ch=='Y'||ch=='y')
				break;
			else if(ch=='N' ||ch=='n')
			{
				//将航班信息写入文件
				WriteFileforFlight(filenameFlight);
				return;
			}
		}
	}
	//尾插法 END
	*/

}
//管理员功能:修改航班信息
void ManagerModFlight()
{
	FlightInfoNode* p = 0;
	char id[10], ch;
	system("cls");
	printf("请输入需要修改信息的航班号:");
	while (1)
	{
		scanf("%s", id);
		p = searchFlightById(id);
		if (p == 0)
		{
			printf("未找到该航班号的航班,是否重新输入航班号(Y/N):\n");
		}
		else
		{
			showFlghtTitle();
			showSingleFlightInfo(p);
			printf("\n\n------------修改信息---------------\n");
			//如果航班信息更改了,可能涉及到退票等处理,因此,需要先判断该航班是否已经售票
			if (p->flightInfo.toatalNmb != p->flightInfo.leftNmb)
			{
				printf("该航班已经售票,只能修改起飞时间、抵达时间、票价、票价折扣、总票量\n");
				//总票量不能小于已售票数,否则就需要退票
				printf("请输入起飞时间(HH:MM):"); scanf("%d:%d", &p->flightInfo.tmStart.hour, &p->flightInfo.tmStart.min);
				printf("请输入降落时间(HH:MM):"); scanf("%d:%d", &p->flightInfo.tmEnd.hour, &p->flightInfo.tmEnd.min);
				printf("请输入航班票价:"); scanf("%d", &p->flightInfo.price);
				printf("请输入票价折扣:"); scanf("%f", &p->flightInfo.zhk);
				printf("请输入总票量:"); scanf("%d", &p->flightInfo.toatalNmb);
			}
			else
			{
				//默认航班号不允许修改
				//printf("请输入航班号:"); scanf("%s",p->flightInfo.id);
				printf("请输入起飞城市:"); scanf("%s", p->flightInfo.start);
				printf("请输入抵达城市:"); scanf("%s", p->flightInfo.end);
				printf("请输入起飞时间(HH:MM):"); scanf("%d:%d", &p->flightInfo.tmStart.hour, &p->flightInfo.tmStart.min);
				printf("请输入降落时间(HH:MM):"); scanf("%d:%d", &p->flightInfo.tmEnd.hour, &p->flightInfo.tmEnd.min);
				printf("请输入航班票价:"); scanf("%d", &p->flightInfo.price);
				printf("请输入票价折扣:"); scanf("%f", &p->flightInfo.zhk);
				printf("请输入总票量:"); scanf("%d", &p->flightInfo.toatalNmb);
				printf("请输入剩余票量:"); scanf("%d", &p->flightInfo.leftNmb);
			}
			printf("修改成功,是否继续修改其它航班(Y/N):");


		}
		rewind(stdin);  //清空输入缓存 vs2015之前的版本可以使用 fflush(stdin);

		while (1)
		{
			ch = getchar();
			getchar();
			if (ch == 'y' || ch == 'Y')
				break;
			else if (ch == 'n' || ch == 'N')
			{
				//将航班信息写入文件
				WriteFileforFlight(filenameFlight);
				return;
			}
			else
				printf("输入不合法,是否继续修改航班信息(Y/N):");
		}
	}


}
//管理员功能:删除航班
void ManagerDeleteFlight()
{
	FlightInfoNode* p = 0, * t;
	char id[10], ch;
	system("cls");
	printf("请输入需要删除的航班号:");
	while (1)
	{
		scanf("%s", id);
		p = searchFlightById(id);
		if (p == 0)
		{
			printf("未找到该航班号的航班,是否继续(Y/N):");
		}
		else
		{
			//找到p的上一个节点
			t = g_flights;
			while (t->next != p)
				t = t->next;
			t->next = p->next; //从链表中删除p
			free(p); //释放p的空间
			printf("删除成功,是否继续(Y/N):");
		}
		//是否继续
		rewind(stdin);  //清空输入缓存 vs2015之前的版本可以使用 fflush(stdin);
		while (1)
		{
			ch = getchar();
			getchar();
			if (ch == 'y' || ch == 'Y')
				break;
			else if (ch == 'n' || ch == 'N')
			{
				//将航班信息写入文件
				WriteFileforFlight(filenameFlight);
				return;
			}
			else
				printf("输入不合法,是否继续删除航班信息(Y/N):");
		}
	}
}

//管理员功能:查询航班-查询航班顾客
void ManagerSearchCustomer()
{
	FlightInfoNode* p;
	TicksInfoNode* tk;
	char id[10], ch;
	int flag = 0;
	while (1)
	{
		system("cls");
		printf("请输入需要查询的航班号:");
		scanf("%s", id);
		flag = 0;
		p = searchFlightById(id);
		if (p == 0)
			printf("未找到该航班,是否继续查找(Y/N):");
		else
		{
			//从订票信息中查找顾客
			tk = g_ticks->next;
			while (tk)
			{
				//显示账号、姓名、身份证
				if (tk->data.flight == p)
				{
					flag = 1;
					printf("%20s %20s %20s\n", tk->data.customer->customer.username, tk->data.customer->customer.name, tk->data.customer->customer.card);
				}
			}
			if (flag == 0)
				printf("该航班没有顾客。是否继续查找(Y/N):");
			else
				printf("本次查询完毕。是否继续查找(Y/N):");
		}
		rewind(stdin);  //清空输入缓存 vs2015之前的版本可以使用 fflush(stdin);
		while (1)
		{
			ch = getchar();
			getchar();
			if (ch == 'y' || ch == 'Y')
				break;
			else if (ch == 'n' || ch == 'N')
				return;
			else
				printf("输入不合法,是否继续查找(Y/N):");
		}

	}
}

//管理员功能:显示所有航班
void ManagerShowAllFlight()
{
	FlightInfoNode* p = g_flights->next;
	system("cls");
	showFlghtTitle();
	while (p)
	{
		showSingleFlightInfo(p);
		p = p->next;
	}
	system("pause");
}
//管理员功能:查询航班
void ManagerSearch()
{
	FlightInfoNode* p;
	char id[10];
	int op;
	while (1)
	{
		system("cls");
		printf("1.根据航班号查询\n");
		printf("2.根据起飞地点和抵达地点查询\n");
		printf("3.查询航班顾客\n");
		printf("4.显示所有航班\n");
		printf("5.结束查询\n");
		printf("请选择:");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			system("cls");
			printf("请输入航班号:");
			scanf("%s", id);
			p = searchFlightById(id); //按照航班号查询
			if (p)
			{
				showFlghtTitle();
				showSingleFlightInfo(p);
			}
			system("pause");
			break;
		case 2:
			system("cls");
			searchFlightByPlace();    //根据起飞地点和抵达地点查询
			system("pause");
			break;
		case 3:
			ManagerSearchCustomer(); //查询航班顾客
			break;
		case 4:
			ManagerShowAllFlight();  //显示所有航班
			break;
		case 5:
			return;
		}
	}
}

//管理员功能:根据航班号排序
void ManagerSort()
{
	FlightInfoNode* p, * q, * tail;
	int op;

	while (1)
	{
		system("cls");
		printf("1.升序\n");
		printf("2.降序\n");
		printf("3.结束排序\n");
		printf("请选择:");
		scanf("%d", &op);

		if (op == 3)
			return;
		else if (op == 1 || op == 2)
		{
			tail = NULL;
			while ((g_flights->next->next) != tail)
			{
				p = g_flights;
				q = g_flights->next;
				while (q->next != tail)
				{
					if ((op == 1 && strcmp(q->flightInfo.id, q->next->flightInfo.id) > 0) || (op == 2 && strcmp(q->flightInfo.id, q->next->flightInfo.id) < 0)) //升序排列 /降序
					{
						p->next = q->next;
						q->next = q->next->next;
						p->next->next = q;
						q = p->next;
					}
					q = q->next;
					p = p->next;
				}
				tail = q;
			}
			//排序完后,显示
			ManagerShowAllFlight();

		}
	}

}


//管理员功能入口
void DealManager()
{
	int op;

	while (1)
	{
		system("cls");
		printf("1.录入航班信息\n");
		printf("2.修改航班信息\n");
		printf("3.删除航班信息\n");
		printf("4.查询航班信息\n");
		printf("5.根据航班号排序\n");
		printf("6.退出\n");
		printf("请选择:");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			ManagerInput(); //录入航班信息
			break;
		case 2:
			ManagerModFlight(); //修改航班信息
			break;
		case 3:
			ManagerDeleteFlight(); //删除航班信息 
			break;
		case 4:
			ManagerSearch();//查询航班信息
			break;
		case 5:
			ManagerSort(); //根据航班号排序
			break;
		case 6:
			return;
		}

	}

}


//判断账户是否已经存在(用于注册和登录使用)
CustomerNode* isCustomerExist(char* username)
{
	CustomerNode* p = g_customers->next;
	while (p)
	{
		if (strcmp(p->customer.username, username) == 0)
			return p;
		else
			p = p->next;
	}
	return 0;
}


//客户功能:注册
void CustomerRegister()
{
	CustomerNode* t, * p;
	system("cls");
	t = (CustomerNode*)malloc(sizeof(CustomerNode));
	t->next = NULL;
	printf("请输入账号:");
	//判断账号是否已经存在
	while (1)
	{
		scanf("%s", t->customer.username);
		if (isCustomerExist(t->customer.username))
			printf("该账号已存在,请重新输入:");
		else
			break;
	}

	printf("请输入密码:");
	scanf("%s", t->customer.pwd);
	printf("请输入姓名:");
	scanf("%s", t->customer.name);
	printf("请输入身份证号:");
	scanf("%s", t->customer.card);
	//插入链表结尾
	p = g_customers;
	while (p->next)
		p = p->next;
	p->next = t;
	//更新文件
	WreiteFileforCustomer(filenameCus);
	printf("注册成功!");
	system("pause");
}

//登录
int CustomerLogin()
{
	int cnt = 0;
	char username[20];
	char pwd[10];
	CustomerNode* p = 0;
	system("cls");
	printf("请输入用户名:");
	while (cnt < 5)//最多输入5次
	{
		cnt++;
		scanf("%s", username);
		p = isCustomerExist(username);
		if (p)
			break;
		else
		{
			if (cnt == 5)
			{
				printf("输入错误次数过多,请10分钟后再登录!");
				system("pause");
				return 0;
			}
			else
				printf("该用户不存在,请重新输入:");

		}
	}
	cnt = 0;
	//输入密码
	printf("请输入密码:");
	while (cnt < 5)
	{
		scanf("%s", pwd);
		cnt++;
		if (strcmp(p->customer.pwd, pwd) == 0)
		{
			break;
		}
		else
		{
			if (cnt == 5)
			{
				printf("输入次数过多,请10分钟后重试!\n");
				system("pause");
				return 0;
			}
			else
				printf("密码跟账号不匹配,请重新输入:");
		}
	}
	g_customersCurrentLogin = p; //记录当前登录账号,方便购票时直接填入用户信息
	printf("登录成功!\n");
	system("pause");
	return 1;
}

//购票
void BuyTicket()
{
	char start[20], dst[20], id[10];
	int flag = 0;
	FlightInfoNode* p = g_flights->next;
	TicksInfoNode* ticket, * pt;

	if (g_customersCurrentLogin == 0)
	{
		printf("请先登录!\n");
		system("pause");
		return;
	}


	while (1)
	{
		system("cls");
		printf("请输入起始地点:");
		scanf("%s", start);
		printf("请输入抵达地点:");
		scanf("%s", dst);
		//根据起始地点和目的地点查找复合条件的航班信息
		while (p)
		{
			if (strcmp(p->flightInfo.start, start) == 0 && strcmp(p->flightInfo.end, dst) == 0 && p->flightInfo.leftNmb > 0) //这里把没有座位的航班给剔除掉了,否则下面选择航班的时候可能会出BUG
			{
				if (flag == 0)
				{
					showFlghtTitle();
					flag = 1;
				}
				showSingleFlightInfo(p);
			}

			p = p->next;
		}
		if (flag == 0)
			printf("没有复合条件的航班,请重新输入!\n");
		else
		{
			//从上述符合条件的航班中选择一个航班,这里不在判断航班号是否正确,默认航班号是正确的,所以再输入时注意航班号正确输入
			while (1)
			{
				printf("请输入所购机票的航班号:");  //因为再上面已经把无座位的航班已经筛除了,所以这里没有在做是否有座位的判断
				scanf("%s", id);
				p = searchFlightById(id);
				//设置航班的剩余座位信息
				if (p->flightInfo.leftNmb == 0)
					printf("该航班已无座位,");
				else
				{
					p->flightInfo.leftNmb -= 1;
					//更新航班信息文件
					WriteFileforFlight(filenameFlight);
					//更新购票信息
					pt = (TicksInfoNode*)malloc(sizeof(TicksInfoNode));
					pt->data.customer = g_customersCurrentLogin;
					pt->data.flight = p;
					pt->next = NULL;
					//插入链表末尾
					ticket = g_ticks;
					while (ticket->next)
						ticket = ticket->next;
					ticket->next = pt;
					//写入文件
					WriteFileTickets(filenameTicks);
					break;
				}

			}
			printf("购票成功!\n");
			system("pause");
			return;
		}
	}
}

//客户功能:退票
void CustomerDelTicket()
{
	FlightInfoNode* p = 0;
	TicksInfoNode* ticket = 0;
	char id[20];
	int flag = 0;
	system("cls");
	if (g_customersCurrentLogin == 0)
	{
		printf("请先登录!\n");
		system("pause");
		return;
	}
	//根据用户查找用户的订票信息
	ticket = g_ticks->next;

	while (ticket)
	{
		if (ticket->data.customer == g_customersCurrentLogin)
		{
			if (flag == 0)
			{
				flag = 1;
				printf("当前的购票信息:\n");
				showFlghtTitle();
			}
			showSingleFlightInfo(ticket->data.flight);
		}
		ticket = ticket->next;
	}

	if (flag == 0)
	{
		printf("目前尚无购票信息!\n");
		system("pause");
		return;
	}
	else
	{
		printf("\n请输入需要退票的航班号:");//考虑到一个人可能订购了多张机票
		scanf("%s", id);
		p = searchFlightById(id);
		p->flightInfo.leftNmb += 1; //剩余票数+1 
		//更新文件
		WriteFileforFlight(filenameFlight);
		WriteFileTickets(filenameTicks); //因为1个航班只有一个指针,而购票信息中存储的是航班指针,所以修改了航班信息后,购票信息中的航班信息会随着更改,只需要更新文件即可
		printf("退票成功\n");
		system("pause");
	}

}
//客户功能:查询
void CustomerSearch()
{
	int op, flag = 0;;
	TicksInfoNode* p;
	while (1)
	{
		system("cls");
		printf("1.查询订票信息\n");
		printf("2.查询航班信息\n");
		printf("3.结束查询\n");
		printf("请选择:");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			p = g_ticks;
			flag = 0;
			while (p)
			{
				if (p->data.customer == g_customersCurrentLogin)
				{
					if (flag == 0)
					{
						flag = 1;
						showFlghtTitle();
					}
					showSingleFlightInfo(p->data.flight);
				}

				p = p->next;
			}
			if (flag == 0)
				printf("目前尚无购票信息!\n");
			break;
		case 2:
			system("cls");
			searchFlightByPlace();
			break;
		case 3:
			return;
		}
		system("pause");
	}
}
//客户功能入口
void DealCustomer()
{
	int op;
	while (1)
	{
		system("cls");
		printf("1.注册\n");
		printf("2.登录\n");
		printf("3.购票\n");
		printf("4.退票\n");
		printf("5.查询\n");
		printf("6.退出\n");
		printf("请选择:");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			CustomerRegister();
			break;
		case 2:
			CustomerLogin();
			break;
		case 3:
			BuyTicket();
			break;
		case 4:
			CustomerDelTicket();
			break;
		case 5:
			CustomerSearch();
			break;
		case 6:
			g_customersCurrentLogin = 0; //将当前登录账号置空
			return;
		}
	}
}
//入口函数
int main()
{
	int op;
	ReadFile(filenameCus, filenameFlight, filenameTicks);
	while (1)
	{
		system("cls");
		printf("-----------------------------------\n");
		printf("       欢迎使用机票管理系统\n");
		printf("       1.管理员身份登录\n");
		printf("       2.顾客登录\n");
		printf("       3.退出\n");
		printf("-----------------------------------\n");
		printf("请选择:");
		scanf("%d", &op);
		switch (op)
		{
		case 1:
			DealManager();
			break;
		case 2:
			DealCustomer();
			break;
		case 3:
			return 0;
		}
	}
	return 0;
}

  • 28
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qfl_sdu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值