c语言-航班订票系统

#include
#include
#include
#include
#include          

typedef struct flightnode         //定义飞机航班链表
{
	char flight_num[10];  
	char start_time[10];  
	char end_time[10];    
	char start_place[20]; 
	char end_place[20];   
	float price;          
	float price_discount; 
	int left;          
	int isFull;           
	struct flightnode *next;
}flightnode;

typedef struct passengernode      //定义乘客链表
{
	char name[20];             
	char ID_num[20];           
	char flight_num[10];       
	int order_num;             
	int ticket_num;            
	struct passengernode *next;
}passengernode;               

typedef struct passengerList      //乘客链表的头指针,尾指针
{
	passengernode *head;
	passengernode *rear;
}passengerList;

void init_flight(flightnode *&h)  //初始化航班链表为空表 定义并引用h为头结点
{
	h = (flightnode *)malloc(sizeof(flightnode));            
	if(h==NULL) exit(0);          
	h->next = NULL;               
}

void init_passengerList(passengerList *&pList)                   //定义乘客链表为空链表
{
	pList = (passengerList *)malloc(sizeof(passengerList));
	pList->head = (passengernode *)malloc(sizeof(passengernode)); 
	pList->rear = pList->head;                                           
	pList->rear->order_num = 0;                                       
	pList->head->next = NULL;                                        
}

void save_passenger(passengerList *PList)           //保存文件(以二进制形式保存 存到.dat文件中)   passenger.dat 
{
	FILE* fp = fopen("passenger.dat","wb");
	if(fp == NULL)
		return;
	passengernode *temp = PList->head->next;        //temp指针指向链表的首节点
	while(temp!=NULL)
	{
		fwrite(temp,sizeof(passengernode),1,fp);
		temp = temp->next;
	}
	fclose(fp);
}

void load_passenger(passengerList *PList)           //把文件中的乘客信息导入到乘客链表中
{
	FILE* fp = fopen("passenger.dat","rb");
	if(fp == NULL)
		return;
	passengernode *q;
	int n;                                          //是否成功写入的标志量
	while(!feof(fp))
	{
		q = (passengernode *)malloc(sizeof(passengernode));
		n = fread(q,sizeof(passengernode),1,fp);
		if(n!=1)
			break;
		PList->rear->next=q;             //头插法
		PList->rear=q;
	}
	PList->rear->next = NULL;
	fclose(fp);
}

void save_flight(flightnode *h)
{
	FILE* fp = fopen("flightList.dat","wb");
	if(fp == NULL)
		return;
	flightnode *temp = h->next;
	while(temp != NULL)
	{
		fwrite(temp,sizeof(flightnode),1,fp);
		temp = temp->next;
	}
	fclose(fp);
}

void load_flight(flightnode *&h)               //从文件中将信息导入到航班链表中
{
	flightnode *pt = h;
	FILE* fp = fopen("flightList.dat","rb");
	if(fp == NULL)
		return;
	flightnode *q;
	int n;
	while(!feof(fp))
	{
		q = (flightnode *)malloc(sizeof(flightnode));
		n = fread(q,sizeof(flightnode),1,fp);
		if(n!=1)
			break;
		pt->next = q;
		pt = q;
	}
	pt->next = NULL;
	fclose(fp);
}

void insert_flight(flightnode *&h,char* flight_num,char* start_place,char* end_place,char *start_time,char* end_time,float price,float price_discount,int left,int isFull)
{
	flightnode *q;                                      //q指向新节点
	flightnode *p = h;                                  //p指向航班链表的头节点
	q = (flightnode *)malloc(sizeof(flightnode));
	strcpy(q->flight_num,flight_num);
	strcpy(q->start_place,start_place);
	strcpy(q->end_place,end_place);
	strcpy(q->start_time,start_time);
	strcpy(q->end_time,end_time);
	q->price = price;
	q->price_discount = price_discount;
	q->left = left;
	q->isFull = isFull;
	q->next = p->next;                                  //头插法
	p->next = q;                                    
	p = p->next;
}

void insert_passengerList(flightnode *&h,passengerList *&PList,char *name,char *ID_num,char *flight_num,int ticket_num)
{
	flightnode *p = h->next;                         //p指向乘客链表的首节点
    for(; p!= NULL; p=p->next)
    {
    	if(strcmp(p->flight_num,flight_num) == 0)
    	{
    		p->left = p->left - ticket_num;          //更新实时的剩余座位数
    		if(p->left == 0)
    		{
    			p->isFull = 1;
    		}
    	}
    }
    passengernode *q  = (passengernode *)malloc(sizeof(passengernode));   //新建q节点,存放新的客户信息
    strcpy(q->name, name); 
    strcpy(q->ID_num, ID_num);
    strcpy(q->flight_num, flight_num);
    q->ticket_num = ticket_num;
    q->next = NULL;
    PList->rear->next = q;         //尾插法
    q->order_num = PList->rear->order_num+1;
    PList->rear = q;
}

void add_flight(flightnode *&h)
{
	flightnode *p = h;
	char flight_num[10],start_time[10],end_time[10],start_place[20],end_place[20];
	int left,isFull,mark = 1;
	float price,price_discount;
	for(;p->next!=NULL;p=p->next){}     //p指针指向尾节点 尾插法
	while(mark == 1)
	{
		printf("\t\t 请输入您需要增加的航班号: ");
		scanf("%s",flight_num);
		printf("\t\t 请输入出发地: ");
		scanf("%s",start_place);
		printf("\t\t 请输入目的地: ");
		scanf("%s",end_place);
		printf("\t\t 请输入出发时间: ");
		scanf("%s",start_time);
		printf("\t\t 请输入结束时间: ");
		scanf("%s",end_time);
		printf("\t\t 请输入航班价格: ");
		scanf("%f",&price);
		printf("\t\t 请输入是否有折扣信息(例:7折 输入0.7): ");
		scanf("%f",&price_discount);
		printf("\t\t 请输入剩余座位数: ");
		scanf("%d",&left);
		printf("\t\t 请输入是否满仓:(0表示没有满仓  1表示满仓) ");
		scanf("%d",&isFull);
		insert_flight(p,flight_num,start_place,end_place,start_time,end_time,price,price_discount,left,isFull);
		printf("\t\t 增加航班%s 成功!\n",flight_num);
		printf("\t\t 是否继续录入航班信息(1 表示继续录入;0 表示停止录入).\n");
		printf("\t\t 请输入: ");
		scanf("%d",&mark);
	}
}

int flight_num_check(flightnode *h,char *flight_num)
{
	flightnode *p=h;              //p指针指向航班链表的首节点
	printf("%-8s%-12s%-12s%-10s%-10s%-8s%-8s%-8s%-10s\n","航班号","起飞城市","抵达城市","起飞时间","抵达时间","价格","折扣","空座数","是否满仓");    //提示输入信息格式
	for(;p!=NULL;p = p->next) 
	{
		if(strcmp(p->flight_num,flight_num) == 0)
		{
			printf("%-8s%-12s%-12s%-10s%-10s%-8.2f%-8.2f%-8d%-10d\n",p->flight_num, p->start_place, p->end_place, p->start_time,p->end_time, p->price, p->price_discount, p->left, p->isFull);  //找到航班号 进行输出
			return 1;
		}
	}
	printf("\t\t  抱歉,没有航班为%s 的航班信息!\n",flight_num);
	return 0;
}

int place_check(flightnode *h,char *start_place,char *end_place)    //按照起始地点 结束地点查询
{
	flightnode *p = h;            //p指针 指向航班链表的首节点
	int mark = 0;
	printf("%-8s%-12s%-12s%-10s%-10s%-8s%-8s%-8s%-10s\n","航班号","起飞城市","抵达城市","起飞时间","抵达时间","价格","折扣","空座数","是否满仓");    //提示输入信息格式
	for(;p!=NULL;p = p->next)
	{
		if(strcmp(p->start_place, start_place) == 0 && (strcmp(p->end_place, end_place) == 0))
		{
			printf("%-8s%-12s%-12s%-10s%-10s%-8.2f%-8.2f%-8d%-10d\n",p->flight_num, p->start_place, p->end_place, p->start_time,p->end_time, p->price, p->price_discount, p->left, p->isFull);    //相等 输出航班相关信息
			mark = 1;
		}
	}
	if(mark == 0)
	{
		printf("\t\t 抱歉,没有从%s 到%s 的航班信息!\n",start_place,end_place);
		return 0;
	}
	return 1;
}

void check_all_flight(flightnode *h)            //浏览所有航班
{
	flightnode *p = h;
	int mark = 0;
	printf("%-8s%-12s%-12s%-10s%-10s%-8s%-8s%-8s%-10s\n","航班号","起飞城市","抵达城市","起飞时间","抵达时间","价格","折扣","空座数","是否满仓");    //提示输入信息格式
	for(;p!=NULL; p=p->next)
	{
		printf("%-8s%-12s%-12s%-10s%-10s%-8.2f%-8.2f%-8d%-10d\n",p->flight_num, p->start_place, p->end_place, p->start_time,p->end_time, p->price, p->price_discount, p->left, p->isFull);    //输出相关信息
		mark = 1;
	}
	if(mark == 0)
		printf("\t\t  航班信息为空!\n");
}

void flight_check(flightnode *h)
{
	flightnode *p=h->next;                      //p指针指向航班链表的首节点
	char flight_num[10],start_place[20],end_place[20];
	char a; 
	printf("\t\t 请选择航班查询方式:\n");
	printf("\t\t 1表示按航班号进行查询;\n");
	printf("\t\t 2表示按起飞到达城市进行查询;\n");
	printf("\t\t 3表示浏览全部航班信息.\n\t\t 请选择输入:");
	a = getch();
	printf("%c\n",a);
	if(a ==  '1') 
	{
		printf("\t\t 请输入航班号:");
		scanf("%s",flight_num);
		flight_num_check(p,flight_num);
	}
	else if(a == '2')
	{
		printf("\t\t 请输入起飞城市:");
		scanf("%s",start_place);
		printf("\t\t 请输入抵达城市:");
		scanf("%s",end_place);
		place_check(p,start_place,end_place);
	}
	else if(a == '3')
	{
		check_all_flight(p);
	}
	else
		return;
} 


int find_same_flight(flightnode *h,char *flight_num)  //如果没有你选择的航班满了的话 提示的可选择的其他航班
{
	flightnode *t = h->next,*p = h->next;            //t指针指向航班链表的首节点 p指针指向乘客链表的首节点
	int mark = 0;
	printf("%-8s%-12s%-12s%-10s%-10s%-8s%-8s%-8s%-10s\n","航班号","起飞城市","抵达城市","起飞时间","抵达时间","价格","折扣","空座数","是否满仓");        //提示输入信息格式
	while(t != NULL && strcmp(t->flight_num,flight_num)!=0) t=t->next;     //遍历到了最后一个节点 或者查找到第一个目标节点
	while(p != NULL)
	{
		if((strcmp(t->start_place,p->start_place) == 0) && (strcmp(t->end_place,p->end_place) == 0) && (strcmp(t->flight_num,p->flight_num)!=0))   //出发点和目的地相同 并且和那个满的航班号还不相同
		{
			printf("%-8s%-12s%-12s%-10s%-10s%-8.2f%-8.2f%-8d%-10d\n",p->flight_num, p->start_place, p->end_place, p->start_time,p->end_time, p->price, p->price_discount, p->left, p->isFull);   //输出所有可选航班
			mark = 1;
		}
		p = p->next;
	}
	if(mark == 0)             //没有其他航班的时候该怎么做
	{
		printf("\t\t 抱歉, 没有可选航班!");
		return 0;
	}
	return 1;
}

int book(flightnode *&h,passengerList *&PList)
{
	char name[20];
	char ID_num[20];
	char flight_num[10];
	char start_place[20];
	char end_place[20];
	int ticket_num;
	int k;                              //没票的时候 想不想买别的票的时候  标志量
	flightnode *p = h->next;            //p指向航班链表的首节点
	printf("\t\t 请输入信息:\n");
	printf("\t\t 请输入起飞城市:");
	scanf("%s",start_place);
	printf("\t\t 请输入抵达城市:");
	scanf("%s",end_place);
	if(place_check(h,start_place,end_place) == 1)          //place_check同时会输出所有符合用户需求的航班
	{
		printf("\t\t 航班号:");
		scanf("%s",flight_num);
		while(p != NULL)
		{
			if(strcmp(p->flight_num,flight_num) == 0)
			{
				printf("\t\t 姓名:");
				scanf("%s",name);
				printf("\t\t 证件号码:");
				scanf("%s",ID_num);
				printf("\t\t 订票数量:");
				scanf("%d",&ticket_num);
				if(p->left > 0 && p->left >= ticket_num)   //判断是否剩余充足的座位
				{
					insert_passengerList(h,PList,name,ID_num,flight_num,ticket_num);
					printf("\t\t 你应付金额¥%6.2f.\n",p->price * p->price_discount * ticket_num);
					getch();
					printf("\t\t 恭喜您,订票成功啦!\n");
					return 1;
				}
				else
				{
					printf("\t\t ***很遗憾,该航班已满:!***\n");
					printf("\t\t ***如您想要选择其他航班请输入---1\n\t\t *** 不选则输入---0***\n");
					printf("\t\t 请输入数字进行选择:");
					scanf("%d",&k);
					if(k==1)
					{
						printf("\t\t 此航线上的其他航班有:\n");
						if(find_same_flight(h,flight_num) == 1)              //该航班已经没有了座位 开始查找下一个节点 此时进行传参flight_num
						{
							printf("\t\t 请输入您选的航班:");
							scanf("%s",flight_num);
							insert_passengerList(h, PList, name, ID_num, flight_num, ticket_num);    //选择成功进行插入操作
							printf("\t\t 恭喜你,订票成功!\n");
							return 1;
						}
					}
					return 0;
				}
			}
			else
				p = p->next;
		}
		if(p==NULL)                            //遍历到了乘客链表的尾节点
			printf("\t\t 对不起,您输入的航班不存在!\n");
	}
	return 0;
}

void delete_flight(flightnode *&h, passengerList *&PList)
{
	flightnode *p,*pr;    //p指向航班链表的首节点 pr指向航班链表的头结点 定义的p即为需要删除的节点 下同
	passengernode *q,*qr;
	char flight_num[10];
	int mark = 1;
	qr = PList->head;
	q = qr->next;
	pr = h;
	p = pr->next;
	printf("\t\t 请输入您要删除的航班号:");
	scanf("%s",flight_num);
	while(p != NULL)
	{
		if(strcmp(flight_num, p->flight_num) == 0)
		{
			pr->next = p->next;   //需要删除的节点 的前一个节点直接指向 需要删除节点的后一个节点
			free(p);
 			printf("\t\t 删除%s 航班成功!\n",flight_num);
 			mark = 0;
 			p = NULL;
		}
		if(pr->next != NULL)
		{
			pr = pr->next;
			p = pr->next;
		}
	}
	if(mark == 1)
		printf("\t\t 无此航班,无法删除!\n");
	else                         //删除顾客链表中的信息  删除了航班信息同时还需要删除
 	{
		while(q != NULL)
		{
			if(strcmp(flight_num, q->flight_num) == 0)
			{
				qr->next = q->next;     //要删除的乘客节点的前一个节点 直接指向要删除节点的后一个节点 进行删除操作
				free(q);
				q = NULL;
			}
			if(qr->next != NULL)
			{
				qr = qr->next;
				q = qr->next;
			}
		}
	}
}

int delete_passenger(passengerList *&PList, flightnode *&h, char *name,char *ID_num)      //退票  删除顾客信息
{
	passengernode *p, *pr = PList->head;     //p指向乘客链表的首节点 pr相当于乘客链表的头指针
	p = pr->next;
	while(p!=NULL)
	{
		if((strcmp(name, p->name)==0) && strcmp(ID_num,p->ID_num)==0)
		{
			for(flightnode *f=h->next; f!=NULL; f=f->next)
			{
				if(strcmp(p->flight_num,f->flight_num) == 0)
				{ 
					f->left = f->left + p->ticket_num;
					f->isFull = 0;
					break;
				}
			}
			pr->next = p->next;              //链表中删除顾客节点
			free(p);
			printf("\t\t 乘客%s,%s 退票成功!\n",name,ID_num);
			return 1;
		}
		pr = pr->next;
		p = pr->next;
	}
	printf("\t\t 无此顾客,无法退票!\n");
	return 0;
}

int check_passenger(passengerList *&PList, char *name, char *ID_num)
{
	passengernode *p, *pr = PList->head;         //p指针指向乘客链表的首节点 pr相当乘客链表的头指针
	p = pr->next;
	while(p != NULL)
	{
		if((strcmp(name, p->name)==0) && strcmp(ID_num,p->ID_num)==0)
		{
			printf("\n\t\t %s您已成功购买过票,您购买的航班号为:%s,您的订单号为:%d",p->name, p->flight_num, p->order_num);
			return 0;
		}
		else
		{
			pr = pr->next;
			p = pr->next;
		}
	}
	printf("\n\t\t %s您没有购票记录,谢谢您的查询", name);
	return 0;
}

void cancel(passengerList *&PList,flightnode *&h)
{
	char name[20],ID_num[20];
	printf("\t\t 请输入您的姓名:");
	scanf("%s",name);
	printf("\t\t 请输入您的证件号:");
	scanf("%s",ID_num);
	delete_passenger(PList, h, name, ID_num);
}

void passenger_check(passengerList *&PList)
{
	char name[20],ID_num[20];
	printf("\t\t 请输入您的名字:");
	scanf("%s",name);
	printf("\t\t 请输入您的证件号:");
	scanf("%s",ID_num);
	check_passenger(PList, name, ID_num);
}

void modify_flight(flightnode *&h,passengerList *&PList)
{
	flightnode *p=h->next;                                    //p指针航班链表的首节点
	char flight_num[10],start_time[10],end_time[10];
	char a;
	printf("\t\t********航班信息修改*******************\n");
	printf("\t\t***************************************\n");
	printf("\t\t*         增加航班------1             *\n");
	printf("\t\t*         删除航班------2             *\n");
	printf("\t\t*         修改航班时间---3            *\n");
	printf("\t\t****************************************");
	printf("\t\t 请选择:");
	a = getch();
	printf("%c\n",a);
	if(a == '1')
		add_flight(h);
	else if(a == '2')
		delete_flight(h,PList);
	else if(a == '3')
	{
		printf("\t\t 请输入要修改的航班的航班号:");
		scanf("%s",flight_num);
		if(flight_num_check(p, flight_num) == 1)
		{
			printf("\t\t 请输入修改后的起飞时间:");
			scanf("%s",start_time);
			printf("\t\t 请输入修改后的抵达时间:");
			scanf("%s",end_time);
			for(; p!=NULL; p=p->next)
			{
				if(strcmp(flight_num, p->flight_num) == 0)
				{
					strcpy(p->start_time, start_time);
					strcpy(p->end_time, end_time);
					printf("\t\t 航班%s 时间修改成功!\n",flight_num);
				}
			}
		}
	}
	else
		return;
}

int main() 
{
	int t = 1;
	char choice;
	flightnode *flight;    //定义航班链表的结构体指针
	passengerList *PList;
	init_flight(flight);
	init_passengerList(PList);
	load_flight(flight);
	load_passenger(PList);

	while(t==1)
	{
		printf("\n"); 
    	printf("\t\t\t***************飞机订票系统菜单***********************\n"); 
   		printf("\t\t\t******************************************************\n"); 
    	printf("\t\t\t*                录入航班信息----------1             *\n"); 
    	printf("\t\t\t*                查询航班信息----------2             *\n"); 
    	printf("\t\t\t*                订购    机票----------3             *\n"); 
    	printf("\t\t\t*                退订    机票----------4             *\n"); 
    	printf("\t\t\t*                查询订票信息----------5             *\n");
    	printf("\t\t\t*                修改航班信息----------6             *\n"); 
    	printf("\t\t\t*                退出    系统----------0             *\n"); 
    	printf("\t\t\t******************************************************\n"); 
    	printf("\t\t\t 请选择服务:"); 
    	choice = getch();
    	printf("%c\n",choice);
    	system("cls");
    	if(choice == '1')
    	{
    		add_flight(flight);
    		getch();
    		system("cls");
		}
		else if(choice == '2')
		{
			flight_check(flight);
			getch();
			system("cls");
		}
		else if(choice == '3')
		{
			book(flight,PList);
			getch();
			system("cls");
		}
		else if(choice == '4')
		{
			cancel(PList,flight);
			getch();
			system("cls"); 
		}
		else if(choice == '5')
		{
			passenger_check(PList);
			getch();
			system("cls");
		}
		else if(choice == '6')
		{
			modify_flight(flight,PList);
			getch();
			system("cls");
		}
		else if(choice == '0')
		{
			printf("\t\t\t 欢迎您使用本系统  再见");
			t = 0; 
		}
	}
	save_flight(flight);
	save_passenger(PList);
	return 0;
}

你可能感兴趣的:(others)