c語言-航班訂票系統

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

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章