火车售票系统

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<stdbool.h>
typedef struct locates
{
	char locate[20];
	int remain_vote;
	char begin_time[30];
	char finish_time[30];
	struct locates* next;
}locates;
typedef struct train
{
	char trainnumber[10];
	locates* locates_list;
	struct train* next;
}train;
typedef struct tickets
{
	char place1[10];
	char place2[10];
	char trainnumber[10];
	char begin_time[30];
	char finish_time[30];
	int nums;
	struct tickets* next;
}tickets;
void writeToFile(tickets* head, const char* filename) {
	FILE* fp = fopen(filename, "w");
	if (fp == NULL) {
		perror("Failed to open file for writing");
		return;
	}

	tickets* current = head;
	while (current != NULL) {
		fprintf(fp, "%s %s %s %s %s %d\n",
			current->place1, current->place2, current->trainnumber,
			current->begin_time, current->finish_time, current->nums);
		current = current->next;
	}
	fclose(fp);
}
tickets* readFromFile(const char* filename) {
	FILE* fp = fopen(filename, "r");
	if (fp == NULL) {
		perror("Failed to open file for reading");
		return NULL;
	}

	tickets* head = NULL, * current = NULL;
	char place1[10], place2[10], trainnumber[10], begin_time[30], finish_time[30];
	int nums;

	while (fscanf(fp, "%9s %9s %9s %29s %29s %d",
		place1, place2, trainnumber, begin_time, finish_time, &nums) == 6) {
		tickets* newNode =(tickets*) malloc(sizeof(tickets));
		if (newNode == NULL) {
			perror("Failed to allocate memory for new node");
			fclose(fp);
			return head; // Return what was successfully read before the error
		}
		strcpy(newNode->place1, place1);
		strcpy(newNode->place2, place2);
		strcpy(newNode->trainnumber, trainnumber);
		strcpy(newNode->begin_time, begin_time);
		strcpy(newNode->finish_time, finish_time);
		newNode->nums = nums;
		newNode->next = NULL;

		if (head == NULL) {
			head = newNode;
			current = newNode;
		}
		else {
			current->next = newNode;
			current = newNode;
		}
	}

	fclose(fp);
	return head;
}
void save_trains_to_file(train* head, const char* filename)//文件存储 
{
	FILE* file = fopen(filename, "w");  // 打开文件用于写入
	if (file == NULL) {
		perror("Failed to open file");
		return;
	}
	train* current_train = head;
	while (current_train != NULL) {
		fprintf(file, "%s\n", current_train->trainnumber);
		locates* current_loc = current_train->locates_list;
		while (current_loc != NULL) {
			fprintf(file, "%s %d %s %s\n", current_loc->locate, current_loc->remain_vote,
				current_loc->begin_time, current_loc->finish_time);
			current_loc = current_loc->next;
		}
		fprintf(file, "-\n");  // 使用特殊字符标记一个火车的locates列表结束
		current_train = current_train->next;
	}
	fclose(file);
}
train* load_trains_from_file(const char* filename) //文件读写
{
	FILE* file = fopen(filename, "r");
	if (file == NULL) {
		perror("Failed to open file");
		return NULL;
	}

	train* head = NULL, * last_train = NULL;
	char line[100];
	int is_new_train = 1;

	while (fgets(line, sizeof(line), file)) {
		if (line[0] == '-') {  // 特殊字符,表示一个火车的locates列表结束
			is_new_train = 1;  // 下一次读取的是新的train节点
			continue;
		}

		if (is_new_train) {  // 读取新的train节点
			train* new_train = (train*)malloc(sizeof(train));
			sscanf(line, "%s", new_train->trainnumber);
			new_train->locates_list = NULL;
			new_train->next = NULL;

			if (last_train == NULL) {
				head = new_train;
			}
			else {
				last_train->next = new_train;
			}
			last_train = new_train;
			is_new_train = 0;
		}
		else {  // 读取新的locates节点
			locates* new_locate = (locates*)malloc(sizeof(locates));
			sscanf(line, "%s %d %s %s", new_locate->locate, &new_locate->remain_vote,
				new_locate->begin_time, new_locate->finish_time);
			new_locate->next = NULL;

			// 将新的locates节点添加到最近添加的train节点的locates_list中
			if (last_train->locates_list == NULL) {
				last_train->locates_list = new_locate;
			}
			else {
				locates* loc_last = last_train->locates_list;
				while (loc_last->next != NULL) {
					loc_last = loc_last->next;
				}
				loc_last->next = new_locate;
			}
		}
	}
	fclose(file);
	return head;
}
// 创建新的火车节点
train* createTrainNode(char trainnumber[]) {
	train* newTrain = (train*)malloc(sizeof(train));
	if (newTrain == NULL) {
		exit(-1);
	}
	strcpy(newTrain->trainnumber, trainnumber);
	newTrain->locates_list = NULL;
	newTrain->next = NULL;
	return newTrain;
}
// 添加沿途站点信息
void addLocate(train* head, char locate[], int remain_vote, char begin_time[], char finish_time[]) {
	locates* newLocate = (locates*)malloc(sizeof(locates));
	if (newLocate == NULL) {
		exit(-1);
	}
	strcpy(newLocate->locate, locate);
	newLocate->remain_vote = remain_vote;
	strcpy(newLocate->begin_time, begin_time);
	strcpy(newLocate->finish_time, finish_time);
	newLocate->next = NULL;

	// 找到火车链表的末尾
	train* current = head;
	// 将新的沿途站点信息添加到火车的locates链表中
	current->locates_list = newLocate;
}
// 打印单个tickets节点的信息
void print_ticket(const tickets* ticket) 
{
			printf("起始地点: %s\n", ticket->place1);
			printf("目的地点: %s\n", ticket->place2);
			printf("列车号: %s\n", ticket->trainnumber);
			printf("开始时间: %s\n", ticket->begin_time);
			printf("结束时间: %s\n", ticket->finish_time);
			printf("票数: %d\n", ticket->nums);
			printf("---------------------\n");
}
// 遍历并打印整个tickets链表
void print_tickets_list(const tickets* head) {
	const tickets* current = head;
	while (current != NULL) {
		print_ticket(current);
		current = current->next;
	}
}
void print_train_details(train* head, const char* number,int* flag) 
{
	train* current = head;
	while (current != NULL) {
		if (strcmp(current->trainnumber, number) == 0) {
			printf("Train Number: %s\n", current->trainnumber);
			locates* loc = current->locates_list;
			while (loc != NULL) {
				printf("目的地: %s ", loc->locate);
				printf("剩余票数: %d ", loc->remain_vote);
				printf("出发时间: %s ", loc->begin_time);
				printf("到达时间: %s", loc->finish_time);
				loc = loc->next;
				if (loc != NULL) printf("\n");  // 在多个地点间添加新行
			}
			return;  // 在打印完详细信息后退出函数
		}
		current = current->next;
	}
	printf("No train found with number %s\n", number);
	*flag = 0;// 如果没找到匹配项,输出提示信息
}
// 将新票据节点添加到列表中
void create_ticket(tickets**head2,const char* place1, const char* place2, const char* trainnumber, const char* begin_time, const char* finish_time, int nums)
{
	tickets* new_ticket = (tickets*)malloc(sizeof(tickets));
	if (new_ticket == NULL) {
		perror("Memory allocation failed");
		return;
	}
	strcpy(new_ticket->place1, place1);
	strcpy(new_ticket->place2, place2);
	strcpy(new_ticket->trainnumber, trainnumber);
	strcpy(new_ticket->begin_time, begin_time);
	strcpy(new_ticket->finish_time, finish_time);
	new_ticket->nums = nums;
	if ((*head2) == NULL)
	{
		(*head2) = new_ticket;
		new_ticket->next = NULL;
		return;
	}
	tickets* tmp = (*head2);
	while (tmp->next != NULL)
	{
		tmp = tmp->next;  // Insert at the head of the list
	}
	 tmp->next = new_ticket;
	 new_ticket->next = NULL;
}
void print_trains_from_to(train* head, const char* start_loc, const char* end_loc,int * flag) {
	train* current_train = head;
	while (current_train != NULL) {
		locates* current_loc = current_train->locates_list;
		bool start_found = false, end_found = false;

		// 遍历每个火车的地点列表查找甲地
		while (current_loc != NULL && !start_found) {
			if (strcmp(current_loc->locate, start_loc) == 0) {
				start_found = true;
				break;
			}
			current_loc = current_loc->next;
		}

		// 如果找到甲地,继续查找直到乙地
		if (start_found) {
			locates* start = current_loc;  // 保存甲地的位置开始打印
			while (current_loc != NULL) {
				if (strcmp(current_loc->locate, end_loc) == 0) {
					end_found = true;
					break;
				}
				current_loc = current_loc->next;
			}

			// 如果也找到乙地,打印从甲地到乙地的信息
			if (end_found) {
			         *flag+=1;
				printf("Train Number: %s\n", current_train->trainnumber);
				while (start != current_loc->next) {  // 包含乙地
					printf("Location: %s, Remaining Votes: %d, Begin Time: %s, Finish Time: %s\n",
						start->locate, start->remain_vote, start->begin_time, start->finish_time);
					start = start->next;
				}
				printf("\n");  // 在火车之间添加一个新行
			}
		}
		current_train = current_train->next;
	}
	if (*flag == 1)
	{
		printf("No train found with number\n");
		*flag = 0;// 如果没找到匹配项,输出提示信息
	}
	
}
void set_in(train** head1)
{
	if ((*head1) == NULL)
	{
		int a = 0;
		printf("输入站点个数");
		scanf("%d", &a);
		char f[10];
		printf("车次");
		scanf("%s", f);
		(*head1) = createTrainNode(f);
		for (int i = 0; i < a; i++)
		{
			char b[10];
			int c;
			char d[10];
			char e[10];
			printf("请输入第%d个站点,座位数,出发时间,到站时间", i + 1);
			scanf("%s %d %s %s", &b, &c, &d, &e);
			addLocate((*head1), b, c, d, e);
		}
	}
	else
	{
		train* train2 = NULL;
		int a = 0;
		printf("输入站点个数");
		scanf("%d", &a);
		char f[10];
		printf("车次");
		scanf("%s", f);
		train2 = createTrainNode(f);
		for (int i = 0; i < a; i++)
		{
			char b[10];
			int c;
			char d[10];
			char e[10];
			printf("请输入第%d个站点,座位数,出发时间,到站时间", i + 1);
			scanf("%s %d %s %s", &b, &c, &d, &e);

			addLocate(train2, b, c, d, e);
		}
		train* current = (*head1);
		while (current->next != NULL) {
			current = current->next;
		}
		current->next = train2;
	}
}
void find_buy(train* head1,tickets **head2)
{
	printf("                               *****************请选项你要查找的方法*************\n");
	printf("                               ****** 1.车次查找 ************* 2. 地方查找 ******\n");
	int choose;
	int flag = 1;
	scanf("%d", &choose);
	if (choose == 1)
	{
		char number1[10];
		printf("请输入车次");
		scanf("%s", number1);
		print_train_details(head1, number1,&flag);
	}
	if (choose == 2)
	{
		printf("请输入你要查找的两个地点");
		char place1[10];
		char place2[10];
		scanf("%s", &place1);
		scanf("%s", &place2);
		print_trains_from_to(head1, place1, place2, &flag);
	}
	if(flag)
	{ 
	printf("\n请输入你要购买的车次与两个地点以及票数");
	char place3[10];
	char place4[10];
	char number2[10];
	int ticketsnums = 0;
	scanf("%s", &number2);
	scanf("%s", &place3);
	scanf("%s", &place4);
	scanf("%d", &ticketsnums);
	train* current = head1;
	while (current != NULL) 
	{
		if (strcmp(current->trainnumber, number2) == 0) 
		{
			locates* current_loc = current->locates_list;
			bool start_found = false, end_found = false;

			// 遍历每个火车的地点列表查找甲地
			while (current_loc != NULL && !start_found) {
				if (strcmp(current_loc->locate, place3) == 0) {
					start_found = true;
					break;
				}
				current_loc = current_loc->next;
			}

			// 如果找到甲地,继续查找直到乙地
			if (start_found)
			{
				locates* start1 = current_loc; 
				locates* start2 = current_loc; // 保存甲地的位置开始打印
				while (current_loc != NULL) {
					if (strcmp(current_loc->locate, place4) == 0) {
						end_found = true;
						break;
					}
					current_loc = current_loc->next;
				}

				// 如果也找到乙地,打印从甲地到乙地的信息
				if (end_found) 
				{
					while (start1 != current_loc->next) 
					{  // 包含乙地
						if (start1->remain_vote < ticketsnums)
						{
							printf("票不够\n");
							return;
						}
						start1 = start1->next;
					}
					char time1[10];
				    strcpy(time1, start2->begin_time);
					while (start2 != current_loc)
					{  // 包含乙地
					        start2->remain_vote-=ticketsnums;
							start2 = start2->next;
					}
					char time2[10];
					strcpy(time2, start2->finish_time);
					create_ticket(head2, place3, place4, number2, time1, time2, ticketsnums);
					return;
				}
			}
		}
		current = current->next;
	}
	}
}
void back_ticket(tickets** head2, tickets** head3)
{ 
	char number1[10];
	int number2;
	tickets* prev = NULL;
	printf("请输入车次与车票数");
	scanf("%s %d", &number1,&number2);
	tickets** tmp = head2;
	while(*tmp)
	{
		if (strcmp((*tmp)->trainnumber, number1) == 0||(*tmp)->nums<number2)
			break;
		(*tmp) = (*tmp)->next;
		if ((*tmp)->next != NULL && strcmp((*tmp)->next->trainnumber, number1) == 0)
			prev = *tmp;
	}
	if ((*tmp)|| (*tmp)->nums < number2)
	{
		create_ticket(head3, (*tmp)->place1, (*tmp)->place2, (*tmp)->trainnumber, (*tmp)->begin_time, (*tmp)->finish_time, (*tmp)->nums);
		(*tmp)->nums -= number2;
	}
	else
		printf("没有该车票或退票数量超出");
}
void menu()//初始界面生成
{
	printf("                               ***************欢迎进出火车售票系统***************\n");
	printf("                               *****************1.查阅信息+购票******************\n");//车票订购
	printf("                               *****************2.车票退订***********************\n");//车票退订
	printf("                               *****************3.车票改签***********************\n");//车票改签
	printf("                               *****************4.车票退订信息*******************\n");//车票退订信息
	printf("                               *****************5.车票订购信息*******************\n");
	printf("                               *****************6.车站信息插入*******************\n");
	printf("                               *****************0.退出系统***********************\n");
}
int main()
{
	train* head1 = NULL;
	head1 = load_trains_from_file("trains.txt");
	tickets* head2 = NULL;
	head2 = readFromFile("ticket1.txt");
	tickets* head3 = NULL;
    head3 = readFromFile("ticket2.txt");
	// 添加几个示例火车信息
	int flag = 0; // 写入示例数据到文件
	// 从文件读取数据
	do
	{
		menu();
		printf("                               *****************请选择你要使用的功能*************\n");
		scanf("%d", &flag);
		switch (flag)
		{
		case 0:
			printf("                               *****************谢谢您的使用*********************\n");
			save_trains_to_file(head1, "trains.txt");
			writeToFile(head2, "ticket1.txt");
			writeToFile(head3,"ticket2.txt");
			break;
		case 1:
			find_buy(head1, &head2);
			break;
		case 2:
			back_ticket(&head2, &head3);
			break;
		case 3:
			back_ticket(&head2, &head3);
			find_buy(head1, &head2);
			break;
		case 4:
			print_tickets_list(head3);
			break;
		case 5:
			print_tickets_list(head2);
			break;
		case 6:
			set_in(&head1);
			break;
		default:
			printf("                                            输入不正确,请重新输入\n\n");
			break;
		}
	} while (flag);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值