#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;
}
火车售票系统
于 2024-06-21 00:39:36 首次发布