Data structure course set up flight booking system (C language version)

Data structure course set up flight booking system (C language version)

Course requirements

(1) Flight management. Design reasonable information for each route, including: starting point and destination station name, flight number, member rating, flight cycle, aircraft model, remaining ticket amount, flight fare, etc. (2)
Customer management. Customer information for booking tickets, including: name, number of tickets booked, ID card, and the amount of space tickets that should be paid.
(3) The main operations and functions realized by the system.
① Search flight: output according to the terminal name: flight number, aircraft model, flight date, remaining ticket quantity and position information, flight fare
② Search flight: output the flight with corresponding information according to the information provided by passengers, which is convenient for passengers to book tickets. And waiting in line to book tickets.
(1) Search flights by origin and destination: output the corresponding flight information according to the origin and destination information input by passengers.
(2) Search all flights: print out the information of all flights.
(3) Query flight by number: output the flight information according to the flight number input by the passenger.
③ Booking business: Query the ticket amount of the flight according to the user's needs (flight number and booking quantity). If there are surplus tickets, it will handle the booking procedures for the customer, output the seat number, and display the amount of space tickets that should be paid. If it is full or the remaining tickets are less than the reservation amount, you need to ask the customer request again.
④ Refund business: According to the information provided by the customer (date, flight number), handle refund procedures for the customer, and refund 55% of the flight fare.
⑤ Input and delete:
(1) Input: Input flight information (starting point, destination, number, aircraft number, flight date, total passengers, remaining tickets, flight fare), if the flight does not exist, insert the flight, if If the flight already exists, the output information is not normal.
(2) Delete: Enter the flight number directly. If it exists, it will be deleted directly. If it does not exist, it will prompt that the flight does not exist.

The division of functional modules of the subject

Functional division

注册管理员
  菜单界面 
	功能选择 
  	  管理员登录
		浏览航班
		  航班清单
	      按航班号查询
	      按起点查询
	      按终点查询
	      按日期查询
	      返回
		用户管理
		  用户清单
	      添加用户
	      修改用户
	      删除用户
	      返回
		航班管理
		  添加航班
		  修改航班
		  删除航班
	      返回
		登出
		用户登录
		  浏览航班
			航班清单
		      按航班号查询
		      按起点查询
		      按终点查询
		      按日期查询
		      返回
	       用户设置
	   	   订票
		   退票
	       购票清单
		   登出
		用户注册
		退出系统 
	结束 

source code

Shown below 源代码.

/********************************************
* 孔令泽航班订票系统
*********************************************/

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <conio.h>
#include <ctype.h>
#include <Windows.h> 

#define RECORD_COUNT_MAX 10     /*用户最多可订余票量*/
#define SHOW_BOOK_PAGE_COUNT 20 /*一页显示的航班条目*/

/*用户权限*/
enum UserRank {
    
    
    NORMAL,                     /*管理员*/
    MANAGER                     /*管理员*/
};

/*用户结构体*/
typedef struct _tUserInfo {
    
    
    char id[128];               /*账号*/
    char name[256];             /*姓名*/
    char password[256];         /*密码*/
    char identity[256];         /*身份证*/
    int rank;                   /*权限*/
    struct _tUserInfo* next;
} UserInfo, * pUserInfo;

/*航班结构体*/
typedef struct _tFlightInfo {
    
    
    char id[128];               /*航班号*/
    char from[256];             /*起点*/
    char to[256];               /*终点*/
    char time[256];             /*日期*/
    double price;               /*价格*/
    int sale;                   /*余票*/
    int total;                  /*总票*/
    struct _tFlightInfo* next;  /*下一个节点*/
} FlightInfo, * pFlightInfo;

/*订票记录结构体*/
typedef struct _tRecordInfo {
    
    
    char user_id[128];                      /*用户账号*/
    char flight_id[RECORD_COUNT_MAX][128];  /*航班号*/
    int count;                              /*订余票量*/
    struct _tRecordInfo* next;              /*下一个节点*/
} RecordInfo, * pRecordInfo;

/*清空输入缓冲区*/
void emptyStdin() {
    
    
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

/*等待按下任意键*/
void waitingPressAnyKey() {
    
    
    emptyStdin();
    getchar();
}

/*清屏*/
void clearScreen() {
    
    
    system("cls");
}

/*添加用户节点,返回链表首节点指针*/
pUserInfo addUserInfoNode(pUserInfo head, pUserInfo node) {
    
    
    if (head) {
    
    
        pUserInfo cursor = head;
        while (cursor->next) {
    
    
            cursor = cursor->next;
        }
        /*将新节点插入到链表尾部*/
        cursor->next = node;
        return head;
    }
    else {
    
    
        /*链表为空返回该节点*/
        return node;
    }
}

/*删除用户节点,返回链表首节点指针*/
pUserInfo removeUserInfoNode(pUserInfo head, pUserInfo node) {
    
    
    if (head) {
    
    
        if (head == node) {
    
    
            /*删除节点为首节点*/
            head = node->next;
            /*删除该节点*/
            free(node);
        }
        else {
    
    
            pUserInfo cursor = head;
            while (cursor->next) {
    
    
                /*找到要删除节点的上一个节点*/
                if (cursor->next == node) {
    
    
                    /*将上一个节点指向删除节点的下一个节点*/
                    cursor->next = node->next;
                    /*删除该节点*/
                    free(node);
                    break;
                }
                cursor = cursor->next;
            }
        }
    }
    return head;
}

/*通过账号查找用户节点*/
pUserInfo findUserInfoNode(pUserInfo head, char* id) {
    
    
    pUserInfo cursor = head;
    while (cursor) {
    
    
        /*匹配用户*/
        if (strcmp(cursor->id, id) == 0) {
    
    
            return cursor;
        }
        cursor = cursor->next;
    }
    return NULL;
}

/*计算用户节点数*/
int countUserInfoNode(pUserInfo head) {
    
    
    pUserInfo cursor = head;
    int count = 0;
    while (cursor) {
    
    
        ++count;
        cursor = cursor->next;
    }
    return count;
}

/*添加航班节点,返回链表首节点指针*/
pFlightInfo addFlightInfoNode(pFlightInfo head, pFlightInfo node) {
    
    
    if (head) {
    
    
        pFlightInfo cursor = head;
        while (cursor->next) {
    
    
            cursor = cursor->next;
        }
        /*将新节点插入到链表尾部*/
        cursor->next = node;
        return head;
    }
    else {
    
    
        /*链表为空返回该节点*/
        return node;
    }
}

/*删除航班节点,返回链表首节点指针*/
pFlightInfo removeFlightInfoNode(pFlightInfo head, pFlightInfo node) {
    
    
    if (head) {
    
    
        if (head == node) {
    
    
            /*删除节点为首节点*/
            head = node->next;
            /*删除该节点*/
            free(node);
        }
        else {
    
    
            pFlightInfo cursor = head;
            while (cursor->next) {
    
    
                /*找到要删除节点的上一个节点*/
                if (cursor->next == node) {
    
    
                    /*将上一个节点指向删除节点的下一个节点*/
                    cursor->next = node->next;
                    /*删除该节点*/
                    free(node);
                    break;
                }
                cursor = cursor->next;
            }
        }
    }
    return head;
}

/*通过账号查找航班节点*/
pFlightInfo findFlightInfoNodeByID(pFlightInfo head, char* id) {
    
    
    pFlightInfo cursor = head;
    while (cursor) {
    
    
        /*匹配航班*/
        if (strcmp(cursor->id, id) == 0) {
    
    
            return cursor;
        }
        cursor = cursor->next;
    }
    return NULL;
}

/*通过起点查找航班节点*/
pFlightInfo findFlightInfoNodeByFrom(pFlightInfo head, char* from) {
    
    
    pFlightInfo cursor = head;
    while (cursor) {
    
    
        /*匹配航班*/
        if (strcmp(cursor->from, from) == 0) {
    
    
            return cursor;
        }
        cursor = cursor->next;
    }
    return NULL;
}

/*通过终点查找航班节点*/
pFlightInfo findFlightInfoNodeByTo(pFlightInfo head, char* to) {
    
    
    pFlightInfo cursor = head;
    while (cursor) {
    
    
        /*匹配航班*/
        if (strcmp(cursor->to, to) == 0) {
    
    
            return cursor;
        }
        cursor = cursor->next;
    }
    return NULL;
}

/*通过日期查找航班节点*/
pFlightInfo findFlightInfoNodeByTime(pFlightInfo head, char* time) {
    
    
    pFlightInfo cursor = head;
    while (cursor) {
    
    
        /*匹配航班*/
        if (strcmp(cursor->time, time) == 0) {
    
    
            return cursor;
        }
        cursor = cursor->next;
    }
    return NULL;
}

/*交换两个航班节点*/
void swapFlightInfoNode(pFlightInfo lhs, pFlightInfo rhs) {
    
    
    pFlightInfo temp = (pFlightInfo)malloc(sizeof(FlightInfo));
    /*计算除next之外要交换的字节数*/
    int size = (int)(((char*)&temp->next) - ((char*)temp));
    memcpy(temp, lhs, size);
    memcpy(lhs, rhs, size);
    memcpy(rhs, temp, size);
    free(temp);
}

/*通过航班编号排序*/
void sortFlightInfoNodeByID(pFlightInfo head) {
    
    
    pFlightInfo index = head;
    while (index) {
    
    
        pFlightInfo target = index;
        pFlightInfo cursor = target->next;
        while (cursor) {
    
    
            /*比较模式*/
            if (strcmp(target->id, cursor->id) > 0) {
    
    
                target = cursor;
            }
            cursor = cursor->next;
        }
        /*交换数据*/
        if (target != index) {
    
    
            swapFlightInfoNode(target, index);
        }
        index = index->next;
    }
}

/*计算航班节点数*/
int countFlightInfoNode(pFlightInfo head) {
    
    
    pFlightInfo cursor = head;
    int count = 0;
    while (cursor) {
    
    
        ++count;
        cursor = cursor->next;
    }
    return count;
}

/*添加记录节点,返回链表首节点指针*/
pRecordInfo addRecordInfoNode(pRecordInfo head, pRecordInfo node) {
    
    
    if (head) {
    
    
        pRecordInfo cursor = head;
        while (cursor->next) {
    
    
            cursor = cursor->next;
        }
        /*将新节点插入到链表尾部*/
        cursor->next = node;
        return head;
    }
    else {
    
    
        /*链表为空返回该节点*/
        return node;
    }
}

/*删除记录节点,返回链表首节点指针*/
pRecordInfo removeRecordInfoNode(pRecordInfo head, pRecordInfo node) {
    
    
    if (head) {
    
    
        if (head == node) {
    
    
            /*删除节点为首节点*/
            head = node->next;
            /*删除该节点*/
            free(node);
        }
        else {
    
    
            pRecordInfo cursor = head;
            while (cursor->next) {
    
    
                /*找到要删除节点的上一个节点*/
                if (cursor->next == node) {
    
    
                    /*将上一个节点指向删除节点的下一个节点*/
                    cursor->next = node->next;
                    /*删除该节点*/
                    free(node);
                    break;
                }
                cursor = cursor->next;
            }
        }
    }
    return head;
}

/*通过账号查找记录节点*/
pRecordInfo findRecordInfoNodeByID(pRecordInfo head, char* id) {
    
    
    pRecordInfo cursor = head;
    while (cursor) {
    
    
        /*匹配用户*/
        if (strcmp(cursor->user_id, id) == 0) {
    
    
            return cursor;
        }
        cursor = cursor->next;
    }
    return NULL;
}

/*计算记录节点数*/
int countRecordInfoNode(pRecordInfo head) {
    
    
    pRecordInfo cursor = head;
    int count = 0;
    while (cursor) {
    
    
        ++count;
        cursor = cursor->next;
    }
    return count;
}

/*将用户信息存储到文件*/
void saveUserInfoFile(const pUserInfo head) {
    
    
    pUserInfo cursor = head;
    FILE* output = fopen("users.txt", "w");
    if (output) {
    
    
        while (cursor) {
    
    
            fprintf(output, "%-16s ", cursor->id);
            fprintf(output, "%-16s ", cursor->name);
            fprintf(output, "%-16s ", cursor->password);
            fprintf(output, "%-16s ", cursor->identity);
            fprintf(output, "%-16d ", cursor->rank);
            fprintf(output, "\n");
            cursor = cursor->next;
        }
        fclose(output);
    }
    else {
    
    
        printf("写文件失败!\n");
    }
}

/*从文件中加载用户信息*/
pUserInfo loadUserInfoFile() {
    
    
    pUserInfo head = NULL;
    FILE* input = fopen("users.txt", "r");
    if (input) {
    
    
        while (1) {
    
    
            pUserInfo account = (pUserInfo)malloc(sizeof(UserInfo));
            memset(account, 0, sizeof(UserInfo));
            if (fscanf(input, "%s", account->id) != 1) break;
            if (fscanf(input, "%s", account->name) != 1) break;
            if (fscanf(input, "%s", account->password) != 1) break;
            if (fscanf(input, "%s", account->identity) != 1) break;
            if (fscanf(input, "%d", &account->rank) != 1) break;
            head = addUserInfoNode(head, account);
        }
        fclose(input);
    }
    else {
    
    
        printf("读文件失败!\n");
    }
    return head;
}

/*清理用户列表,回收内存*/
void clearUserInfoList(pUserInfo head) {
    
    
    while (head) {
    
    
        head = removeUserInfoNode(head, head);
    }
}

/*将航班信息存储到文件*/
void saveFlightInfoFile(const pFlightInfo head) {
    
    
    pFlightInfo cursor = head;
    FILE* output = fopen("flights.txt", "w");
    if (output) {
    
    
        while (cursor) {
    
    
            fprintf(output, "%-16s ", cursor->id);
            fprintf(output, "%-16s ", cursor->from);
            fprintf(output, "%-16s ", cursor->to);
            fprintf(output, "%-16s ", cursor->time);
            fprintf(output, "%-16.2lf ", cursor->price);
            fprintf(output, "%-16d ", cursor->sale);
            fprintf(output, "%-16d ", cursor->total);
            fprintf(output, "\n");
            cursor = cursor->next;
        }
        fclose(output);
    }
    else {
    
    
        printf("写文件失败!\n");
    }
}

/*从文件中加载航班信息*/
pFlightInfo loadFlightInfoFile() {
    
    
    pFlightInfo head = NULL;
    FILE* input = fopen("flights.txt", "r");
    if (input) {
    
    
        while (1) {
    
    
            pFlightInfo account = (pFlightInfo)malloc(sizeof(FlightInfo));
            memset(account, 0, sizeof(FlightInfo));
            if (fscanf(input, "%s", account->id) != 1) break;
            if (fscanf(input, "%s", account->from) != 1) break;
            if (fscanf(input, "%s", account->to) != 1) break;
            if (fscanf(input, "%s", &account->time) != 1) break;
            if (fscanf(input, "%lf", &account->price) != 1) break;
            if (fscanf(input, "%d", &account->sale) != 1) break;
            if (fscanf(input, "%d", &account->total) != 1) break;
            head = addFlightInfoNode(head, account);
        }
        fclose(input);
    }
    else {
    
    
        printf("读文件失败!\n");
    }
    return head;
}

/*清理航班列表,回收内存*/
void clearFlightInfoList(pFlightInfo head) {
    
    
    while (head) {
    
    
        head = removeFlightInfoNode(head, head);
    }
}

/*将记录信息存储到文件*/
void saveRecordInfoFile(const pRecordInfo head) {
    
    
    pRecordInfo cursor = head;
    FILE* output = fopen("records.txt", "w");
    if (output) {
    
    
        while (cursor) {
    
    
            int index;
            fprintf(output, "%-16s ", cursor->user_id);
            for (index = 0; index < RECORD_COUNT_MAX; ++index) {
    
    
                if (strlen(cursor->flight_id[index])) {
    
    
                    fprintf(output, "%-16s ", cursor->flight_id[index]);
                }
                else {
    
    
                    fprintf(output, "%-16s ", "-");
                }
            }
            fprintf(output, "%-16d ", cursor->count);
            fprintf(output, "\n");
            cursor = cursor->next;
        }
        fclose(output);
    }
    else {
    
    
        printf("写文件失败!\n");
    }
}

/*从文件中加载记录信息*/
pRecordInfo loadRecordInfoFile() {
    
    
    pRecordInfo head = NULL;
    FILE* input = fopen("records.txt", "r");
    if (input) {
    
    
        while (1) {
    
    
            int index;
            pRecordInfo account = (pRecordInfo)malloc(sizeof(RecordInfo));
            memset(account, 0, sizeof(RecordInfo));
            if (fscanf(input, "%s", account->user_id) != 1) break;
            for (index = 0; index < RECORD_COUNT_MAX; ++index) {
    
    
                if (fscanf(input, "%s", account->flight_id[index]) != 1) break;
                if (strcmp(account->flight_id[index], "-") == 0) {
    
    
                    strcpy(account->flight_id[index], "");
                }
            }
            if (fscanf(input, "%d", &account->count) != 1) break;
            head = addRecordInfoNode(head, account);
        }
        fclose(input);
    }
    else {
    
    
        printf("读文件失败!\n");
    }
    return head;
}

/*清理记录列表,回收内存*/
void clearRecordInfoList(pRecordInfo head) {
    
    
    while (head) {
    
    
        head = removeRecordInfoNode(head, head);
    }
}

/*显示用户信息*/
void showUser(pUserInfo user) {
    
    
    printf("╔-------------------------------------------------╗\n");
    printf("    账号:%s\n", user->id);
    printf("    姓名:%s\n", user->name);
    printf("    密码:%s\n", user->password);
    printf("    身份证:%s\n", user->identity);
    switch (user->rank) {
    
    
    case NORMAL:
        printf("    权限:%s\n", "普通用户");
        break;
    case MANAGER:
        printf("    权限:%s\n", "管理员");
        break;
    }
    printf("╚-------------------------------------------------╝\n");
}

/*编辑用户信息*/
void editUser(pUserInfo user) {
    
    
    printf("╔-------------------------------------------------╗\n");
    printf("    账号:");
    scanf("%s", user->id);
    printf("    姓名:");
    scanf("%s", user->name);
    printf("    密码:");
    scanf("%s", user->password);
    printf("    身份证:");
    scanf("%s", user->identity);
    printf("    权限:(0:普通用户, 1:管理员)");
    scanf("%d", &user->rank);
    if (user->rank != NORMAL && user->rank != MANAGER) {
    
    
        user->rank = NORMAL;
    }
    printf("╚-------------------------------------------------╝\n");
}

/*显示航班信息*/
void showFlight(pFlightInfo flight) {
    
    
    printf("╔-------------------------------------------------╗\n");
    printf("  ·%-12s → %12s·\n", flight->from, flight->to);
    printf("    航班号:");
    printf("%s\n", flight->id);
    printf("    日期:");
    printf("%s\n", flight->time);
    printf("    价格:");
    printf("%.2lf\n", flight->price);
    printf("    余票:");
    printf("%d\n", flight->total - flight->sale);
    printf("    总票:");
    printf("%d\n", flight->total);
    printf("╚-------------------------------------------------╝\n");
}

/*编辑航班信息*/
void editFlight(pFlightInfo flight) {
    
    
    printf("╔-------------------------------------------------╗\n");
    printf("    航班号:");
    if (strlen(flight->id)) {
    
    
        printf("%s\n", flight->id);
    }
    else {
    
    
        scanf("%s", flight->id);
    }
    printf("    起点:");
    scanf("%s", flight->from);
    printf("    终点:");
    scanf("%s", flight->to);
    printf("    日期:");
    scanf("%s", flight->time);
    printf("    价格:");
    scanf("%lf", &flight->price);
    printf("    总票:");
    scanf("%d", &flight->total);
    printf("╚-------------------------------------------------╝\n");
}

/*显示用户清单选项*/
void showUserListOption(pUserInfo head) {
    
    
    pUserInfo cursor = head;
    while (cursor) {
    
    
        showUser(cursor);
        cursor = cursor->next;
    }
    printf("\n按回车键返回上级菜单...\n");
    waitingPressAnyKey();
}

/*添加用户选项*/
void createUserOption(pUserInfo* head) {
    
    
    pUserInfo user = (pUserInfo)malloc(sizeof(UserInfo));
    memset(user, 0U, sizeof(UserInfo));
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 添加用户 #\n");
    printf("╚------------------------╝\n");
    editUser(user);
    if (findUserInfoNode(*head, user->id)) {
    
    
        free(user);
        printf("\n用户创建失败,存在相同用户!\n");
    }
    else {
    
    
        *head = addUserInfoNode(*head, user);
        /*同步文件信息*/
        saveUserInfoFile(*head);
        printf("\n用户创建成功!\n");
    }
    waitingPressAnyKey();
}

/*修改用户选项*/
void updateUserOption(pUserInfo head, pUserInfo me) {
    
    
    char id[128] = {
    
     0 };
    pUserInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 修改用户 #\n");
    printf("\n");
    printf("     账号:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findUserInfoNode(head, id);
    if (target) {
    
    
        showUser(target);
        printf("╔-------------------------------------------------╗\n");
        printf("    账号:");
        printf("%s\n", target->id);
        printf("    姓名:");
        scanf("%s", target->name);
        printf("    密码:");
        scanf("%s", target->password);
        printf("    身份证:");
        scanf("%s", target->identity);
        if (target != me) {
    
    
            printf("    权限:(0:普通用户, 1:管理员)");
            scanf("%d", &target->rank);
            if (target->rank != NORMAL && target->rank != MANAGER) {
    
    
                target->rank = NORMAL;
            }
        }
        printf("╚-------------------------------------------------╝\n");
        /*同步文件信息*/
        saveUserInfoFile(head);
        printf("\n用户修改成功!\n");
    }
    else {
    
    
        printf("\n未找到该用户!\n");
    }
    waitingPressAnyKey();
}

/*删除用户选项*/
void removeUserOption(pUserInfo* head, pUserInfo me) {
    
    
    char id[128] = {
    
     0 };
    pUserInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 删除用户 #\n");
    printf("\n");
    printf("     账号:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findUserInfoNode(*head, id);
    if (target) {
    
    
        if (target == me) {
    
    
            printf("\n不允许删除自己!\n");
        }
        else {
    
    
            showUser(target);
            *head = removeUserInfoNode(*head, target);
            /*同步文件信息*/
            saveUserInfoFile(*head);
            printf("\n用户删除成功!\n");
        }
    }
    else {
    
    
        printf("\n未找到该用户!\n");
    }
    waitingPressAnyKey();
}

/*显示航班清单选项*/
void showFlightListOption(pFlightInfo head) {
    
    
    clearScreen();
    if (head) {
    
    
        pFlightInfo cursor = head;
        int page_current = 0;
        int page_total = countFlightInfoNode(head);
        page_total = ((page_total - 1) / SHOW_BOOK_PAGE_COUNT) + 1;
        while (cursor) {
    
    
            int count = 0;
            clearScreen();
            printf("╔------------------------╗\n");
            printf("       # 航班清单 #\n");
            printf("╚------------------------╝\n");
            printf("       【%2d/%-2d】\n", ++page_current, page_total);
            while (cursor) {
    
    
                showFlight(cursor);
                cursor = cursor->next;
                if (++count == SHOW_BOOK_PAGE_COUNT) {
    
    
                    break;
                }
            }
            if (cursor) {
    
    
                int option;
                printf("\n【 1 下一页 | 0 返回上级菜单】\n");
                scanf("%d", &option);
                switch (option) {
    
    
                case 1:
                    break;
                case 0:
                    return;
                }
            }
        }
    }
    printf("\n按回车键返回上级菜单...\n");
    waitingPressAnyKey();
}

/*添加航班选项*/
void createFlightOption(pFlightInfo* head) {
    
    
    pFlightInfo flight = (pFlightInfo)malloc(sizeof(FlightInfo));
    memset(flight, 0U, sizeof(FlightInfo));
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 添加航班 #\n");
    printf("╚------------------------╝\n");
    editFlight(flight);
    if (findFlightInfoNodeByID(*head, flight->id)) {
    
    
        free(flight);
        printf("\n航班添加失败,存在相同航班编号!\n");
    }
    else {
    
    
        *head = addFlightInfoNode(*head, flight);
        /*同步文件信息*/
        saveFlightInfoFile(*head);
        printf("\n航班添加成功!\n");
    }
    waitingPressAnyKey();
}

/*修改航班选项*/
void updateFlightOption(pFlightInfo head) {
    
    
    char id[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 修改航班 #\n");
    printf("\n");
    printf("     编号:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByID(head, id);
    if (target) {
    
    
        showFlight(target);
        editFlight(target);
        /*同步文件信息*/
        saveFlightInfoFile(head);
        printf("\n航班修改成功!\n");
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*删除航班选项*/
void removeFlightOption(pFlightInfo* head) {
    
    
    char id[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 删除航班 #\n");
    printf("\n");
    printf("     编号:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByID(*head, id);
    if (target) {
    
    
        showFlight(target);
        *head = removeFlightInfoNode(*head, target);
        /*同步文件信息*/
        saveFlightInfoFile(*head);
        printf("\n航班删除成功!\n");
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*按航班号查询航班选项*/
void searchFlightByIDOption(pFlightInfo head) {
    
    
    char id[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 按航班号查询 #\n");
    printf("\n");
    printf("     航班号:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByID(head, id);
    if (target) {
    
    
        showFlight(target);
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*按起点查询航班选项*/
void searchFlightByFromOption(pFlightInfo head) {
    
    
    char from[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 按起点查询 #\n");
    printf("\n");
    printf("     起点:");
    scanf("%s", from);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByFrom(head, from);
    if (target) {
    
    
        do {
    
    
            showFlight(target);
            target = findFlightInfoNodeByFrom(target->next, from);
        } while (target);
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*按终点查询航班选项*/
void searchFlightByToOption(pFlightInfo head) {
    
    
    char to[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 按终点查询 #\n");
    printf("\n");
    printf("     终点:");
    scanf("%s", to);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByTo(head, to);
    if (target) {
    
    
        do {
    
    
            showFlight(target);
            target = findFlightInfoNodeByTo(target->next, to);
        } while (target);
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*按日期查询航班选项*/
void searchFlightByTimeOption(pFlightInfo head) {
    
    
    char time[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 按日期查询 #\n");
    printf("\n");
    printf("     日期:");
    scanf("%s", time);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByTime(head, time);
    if (target) {
    
    
        do {
    
    
            showFlight(target);
            target = findFlightInfoNodeByTime(target->next, time);
        } while (target);
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*添加订票记录*/
pRecordInfo addRecord(pRecordInfo* head, char* user_id, char* flight_id) {
    
    
    pRecordInfo target = findRecordInfoNodeByID(*head, user_id);
    if (!target) {
    
    
        target = (pRecordInfo)malloc(sizeof(RecordInfo));
        memset(target, 0, sizeof(RecordInfo));
        strcpy(target->user_id, user_id);
        *head = addRecordInfoNode(*head, target);
    }
    if (target->count < RECORD_COUNT_MAX) {
    
    
        int index;
        for (index = 0; index < RECORD_COUNT_MAX; ++index) {
    
    
            if (strlen(target->flight_id[index]) == 0) {
    
    
                strcpy(target->flight_id[index], flight_id);
                ++target->count;
                saveRecordInfoFile(*head);
                return target;
            }
        }
    }
    return NULL;
}

/*删除订票记录*/
pRecordInfo removeRecord(pRecordInfo* head, char* user_id, char* flight_id) {
    
    
    pRecordInfo target = findRecordInfoNodeByID(*head, user_id);
    if (target) {
    
    
        int index;
        for (index = 0; index < RECORD_COUNT_MAX; ++index) {
    
    
            if (strcmp(target->flight_id[index], flight_id) == 0) {
    
    
                memset(target->flight_id[index], 0, 128);
                --target->count;
                if (target->count == 0) {
    
    
                    *head = removeRecordInfoNode(*head, target);
                }
                saveRecordInfoFile(*head);
                return target;
            }
        }
    }
    return NULL;
}

/*订票*/
void reserveFlightOption(pFlightInfo flighthead, pRecordInfo* recordhead, pUserInfo me) {
    
    
    char id[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 订票 #\n");
    printf("\n");
    printf("     航班号:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByID(flighthead, id);
    if (target) {
    
    
        showFlight(target);
        if (target->sale < target->total) {
    
    
            if (addRecord(recordhead, me->id, target->id)) {
    
    
                /*同步文件信息*/
                ++target->sale;
                saveFlightInfoFile(flighthead);
                printf("\n订票成功!\n");
                printf("╔------------------------╗\n");
                printf("      支付费用:%.2lf\n", target->price);
                printf("╚------------------------╝\n");
            }
            else {
    
    
                printf("\n您的订余票量已达上限,无法继续订票!\n");
            }
        }
        else {
    
    
            printf("\n没有余票!\n");
        }
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*退票*/
void refundFlightOption(pFlightInfo flighthead, pRecordInfo* recordhead, pUserInfo me) {
    
    
    char id[128] = {
    
     0 };
    pFlightInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 退票 #\n");
    printf("\n");
    printf("     航班:");
    scanf("%s", id);
    printf("╚------------------------╝\n");
    target = findFlightInfoNodeByID(flighthead, id);
    if (target) {
    
    
        showFlight(target);
        if (target->sale > 0) {
    
    
            if (removeRecord(recordhead, me->id, target->id)) {
    
    
                /*同步文件信息*/
                --target->sale;
                saveFlightInfoFile(flighthead);
                printf("\n退票成功!\n");
                printf("╔------------------------╗\n");
                printf("      退费(50%%):%.2lf\n", target->price * 0.5);
                printf("╚------------------------╝\n");
            }
            else {
    
    
                printf("\n您没有订该航班的票!\n");
            }
        }
    }
    else {
    
    
        printf("\n未找到该航班!\n");
    }
    waitingPressAnyKey();
}

/*订票清单*/
void showRecordOption(pFlightInfo flighthead, pRecordInfo recordhead, pUserInfo me) {
    
    
    pRecordInfo target = NULL;
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 购票清单 #\n");
    printf("\n");
    target = findRecordInfoNodeByID(recordhead, me->id);
    printf("   %-10s%-10s%-10s\n", "航班", "起点", "终点");
    if (target) {
    
    
        int index;
        for (index = 0; index < RECORD_COUNT_MAX; ++index) {
    
    
            char* flight_id = target->flight_id[index];
            pFlightInfo flight = findFlightInfoNodeByID(flighthead, flight_id);
            if (flight) {
    
    
                printf("   %-10s%-10s%-10s\n", flight_id, flight->from, flight->to);
            }
        }
    }
    printf("╚------------------------╝\n");
    waitingPressAnyKey();
}

/*用户设置选项*/
void settingUserOption(pUserInfo head, pUserInfo me) {
    
    
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       # 用户设置 #\n");
    printf("╚------------------------╝\n");
    printf("╔-------------------------------------------------╗\n");
    printf("    账号:");
    printf("%s\n", me->id);
    printf("    姓名:");
    printf("%s\n", me->name);
    printf("    密码:");
    scanf("%s", me->password);
    printf("    身份证:");
    scanf("%s", me->identity);
    printf("╚-------------------------------------------------╝\n");
    /*同步文件信息*/
    saveUserInfoFile(head);
    printf("\n用户设置成功!\n");
    waitingPressAnyKey();
}

/*用户管理菜单*/
void manageUsersOption(pUserInfo* head, pUserInfo me) {
    
    
    int option;
    while (1) {
    
    
        clearScreen();
        printf("╔-------------------------------╗\n");
        printf("         # 用户管理 #\n");
        printf("\n");
        printf("      【1】 用户清单\n");
        printf("      【2】 添加用户\n");
        printf("      【3】 修改用户\n");
        printf("      【4】 删除用户\n");
        printf("      【0】 返回\n");
        printf("\n");
        printf("╚-------------------------------╝\n");
        printf("\n");
        scanf("%d", &option);
        switch (option) {
    
    
        case 1:
            showUserListOption(*head);
            break;
        case 2:
            createUserOption(head);
            break;
        case 3:
            updateUserOption(*head, me);
            break;
        case 4:
            removeUserOption(head, me);
            break;
        case 0:
            return;
        }
    }
}

/*航班浏览菜单*/
void browseFlightsOption(pFlightInfo head) {
    
    
    int option;
    sortFlightInfoNodeByID(head);
    while (1) {
    
    
        clearScreen();
        printf("╔-------------------------------╗\n");
        printf("         # 浏览航班 #\n");
        printf("\n");
        printf("      【1】 航班清单\n");
        printf("      【2】 按航班号查询\n");
        printf("      【3】 按起点查询\n");
        printf("      【4】 按终点查询\n");
        printf("      【5】 按日期查询\n");
        printf("      【0】 返回\n");
        printf("\n");
        printf("╚-------------------------------╝\n");
        printf("\n");
        scanf("%d", &option);
        switch (option) {
    
    
        case 1:
            showFlightListOption(head);
            break;
        case 2:
            searchFlightByIDOption(head);
            break;
        case 3:
            searchFlightByFromOption(head);
            break;
        case 4:
            searchFlightByToOption(head);
            break;
        case 5:
            searchFlightByTimeOption(head);
            break;
        case 0:
            return;
        }
    }
}

/*航班管理菜单*/
void manageFlightsOption(pFlightInfo* head) {
    
    
    int option;
    while (1) {
    
    
        clearScreen();
        printf("╔-------------------------------╗\n");
        printf("         # 航班管理 #\n");
        printf("\n");
        printf("      【1】 添加航班\n");
        printf("      【2】 修改航班\n");
        printf("      【3】 删除航班\n");
        printf("      【0】 返回\n");
        printf("\n");
        printf("╚-------------------------------╝\n");
        printf("\n");
        scanf("%d", &option);
        switch (option) {
    
    
        case 1:
            createFlightOption(head);
            break;
        case 2:
            updateFlightOption(*head);
            break;
        case 3:
            removeFlightOption(head);
            break;
        case 0:
            return;
        }
    }
}

/*登录验证*/
pUserInfo checkLogin(pUserInfo head, char* id, char* password) {
    
    
    pUserInfo target = findUserInfoNode(head, id);
    if (target) {
    
    
        if (strcmp(target->password, password) == 0) {
    
    
            return target;
        }
    }
    return NULL;
}

/*普通用户系统主菜单*/
void mainNormalOption(pUserInfo* userhead, pUserInfo me, pFlightInfo* flighthead, pRecordInfo* recordhead) {
    
    
    while (1) {
    
    
        int option;
        clearScreen();
        printf("╔-------------------------------╗\n");
        printf("       # 孔令泽航班订票系统 #\n");
        printf("\n");
        printf("      【1】 浏览航班\n");
        printf("      【2】 用户设置\n");
        printf("      【3】 订票\n");
        printf("      【4】 退票\n");
        printf("      【5】 购票清单\n");
        printf("      【0】 登出\n");
        printf("\n");
        printf("     账号:%s 姓名:%s 权限:%s\n", me->id, me->name, "普通用户");
        printf("╚-------------------------------╝\n");
        printf("\n");
        scanf("%d", &option);
        switch (option) {
    
    
        case 1:
            browseFlightsOption(*flighthead);
            break;
        case 2:
            settingUserOption(*userhead, me);
            break;
        case 3:
            reserveFlightOption(*flighthead, recordhead, me);
            break;
        case 4:
            refundFlightOption(*flighthead, recordhead, me);
            break;
        case 5:
            showRecordOption(*flighthead, *recordhead, me);
            break;
        case 0:
            return;
        }
    }
}

/*管理员系统主菜单*/
void mainManagerOption(pUserInfo* userhead, pUserInfo me, pFlightInfo* flighthead) {
    
    
    while (1) {
    
    
        int option;
        clearScreen();
        printf("╔-------------------------------╗\n");
        printf("       # 孔令泽航班订票系统 #\n");
        printf("\n");
        printf("      【1】 浏览航班\n");
        printf("      【2】 用户管理\n");
        printf("      【3】 航班管理\n");
        printf("      【0】 登出\n");
        printf("\n");
        printf("     账号:%s 姓名:%s 权限:%s\n", me->id, me->name, "管理员");
        printf("╚-------------------------------╝\n");
        printf("\n");
        scanf("%d", &option);
        switch (option) {
    
    
        case 1:
            browseFlightsOption(*flighthead);
            break;
        case 2:
            manageUsersOption(userhead, me);
            break;
        case 3:
            manageFlightsOption(flighthead);
            break;
        case 0:
            return;
        }
    }
}

/*首次登录,初始化管理员账号*/
void firstLogin(pUserInfo* head) {
    
    
    pUserInfo user = (pUserInfo)malloc(sizeof(UserInfo));
    memset(user, 0U, sizeof(UserInfo));
    clearScreen();
    printf("╔-------------------------------╗\n");
    printf("       #孔令泽航班订票系统#\n");
    printf("   #首次使用,需创建管理员用户#\n");
    printf("\n");
    printf("     账号 : ");
    scanf("%s", user->id);
    printf("     姓名 : ");
    scanf("%s", user->name);
    printf("     密码 : ");
    scanf("%s", user->password);
    printf("     身份证 : ");
    scanf("%s", user->identity);
    user->rank = MANAGER;
    printf("╚-------------------------------╝\n");
    *head = addUserInfoNode(*head, user);
    saveUserInfoFile(*head);
}

/* 输入密码 */
void inputPassword(char password[], int capacity) {
    
    
    int index = 0;
    while (1) {
    
    
        /* 获取用户按下的字符(无回显模式) */
        int ch = _getch();
        /* 如果用户按下回车 */
        if (ch == '\n' || ch == '\r') {
    
    
            /* 保证空密码时回车无效 */
            if (index == 0) continue;
            /* 将密码截止,并终止输入 */
            password[index] = '\0';
            putchar('\n');
            break;
        }
        /* 如果用户按下退格符 */
        if (ch == '\b') {
    
    
            /* 密码不为空的情况下才允许退格 */
            if (index > 0) {
    
    
                --index;
                /* 实现退格显示效果 */
                putchar('\b');
                putchar(' ');
                putchar('\b');
            }
        }
        else {
    
    
            /* 忽略用户密码录入中的非打印字符 */
            if (!isgraph(ch)) continue;
            /* 限制密码的有效长度 */
            if (index < capacity) {
    
    
                password[index++] = ch;
                putchar('*');
            }
        }
    }
}

/*用户登录*/
pUserInfo userLogin(pUserInfo head) {
    
    
    char id[128] = {
    
     0 };
    char password[128] = {
    
     0 };
    pUserInfo user = NULL;
    clearScreen();
    printf("╔-------------------------------╗\n");
    printf("   # 欢迎登录航班订票系统 #\n");
    printf("\n");
    printf("\n");
    printf("     账号 : ");
    scanf("%s", id);
    printf("     密码 : ");
    inputPassword(password, 10);
    printf("╚-------------------------------╝\n");
    return checkLogin(head, id, password);
}

/*用户登录*/
void login(pUserInfo* userhead, pFlightInfo* flighthead, pRecordInfo* recordhead) {
    
    
    pUserInfo me = NULL;
    do {
    
    
        me = userLogin(*userhead);
        if (!me) {
    
    
            printf("\n登录失败,账号或密码错误!\n");
            waitingPressAnyKey();
        }
    } while (!me);
    switch (me->rank) {
    
    
    case NORMAL:
        mainNormalOption(userhead, me, flighthead, recordhead);
        break;
    case MANAGER:
        mainManagerOption(userhead, me, flighthead);
        break;
    }
}

/*用户注册*/
void regist(pUserInfo* head) {
    
    
    pUserInfo user = (pUserInfo)malloc(sizeof(UserInfo));
    memset(user, 0U, sizeof(UserInfo));
    clearScreen();
    printf("╔------------------------╗\n");
    printf("       #用户注册#\n");
    printf("╚------------------------╝\n");
    printf("╔-------------------------------------------------╗\n");
    printf("    账号:");
    scanf("%s", user->id);
    printf("    姓名:");
    scanf("%s", user->name);
    printf("    密码:");
    scanf("%s", user->password);
    printf("    身份证:");
    scanf("%s", user->identity);
    printf("╚-------------------------------------------------╝\n");
    if (findUserInfoNode(*head, user->id)) {
    
    
        free(user);
        printf("\n用户创建失败,存在相同用户!\n");
    }
    else {
    
    
        *head = addUserInfoNode(*head, user);
        /*同步文件信息*/
        saveUserInfoFile(*head);
        printf("\n用户注册成功!\n");
    }
    waitingPressAnyKey();
}

/*进入系统*/
void process(pUserInfo* userhead, pFlightInfo* flighthead, pRecordInfo* recordhead) {
    
    
    while (1) {
    
    
        int option;
        clearScreen();
        printf("╔-------------------------------╗\n");
        printf("       # 孔令泽航班订票系统#\n");
        printf("\n");
        printf("      【1】 用户登录\n");
        printf("      【2】 用户注册\n");
        printf("      【0】 退出系统\n");
        printf("\n");
        printf("╚-------------------------------╝\n");
        printf("\n");
        scanf("%d", &option);
        switch (option) {
    
    
        case 1:
            login(userhead, flighthead, recordhead);
            break;
        case 2:
            regist(userhead);
            break;
        case 0:
            return;
        }
    }
}

int main() {
    
    
    system("title 孔令泽航班订票系统");
    /*修改字体颜色、背景颜色*/
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_BLUE | FOREGROUND_INTENSITY | FOREGROUND_RED | BACKGROUND_INTENSITY);
    /*从文件中加载用户数据*/
    pUserInfo userhead = loadUserInfoFile();
    /*从文件中加载航班数据*/
    pFlightInfo flighthead = loadFlightInfoFile();
    /*从文件中加载记录数据*/
    pRecordInfo recordhead = loadRecordInfoFile();
    /*从文件中加载记录数据*/
    if (!userhead) {
    
    
        firstLogin(&userhead);
    }
    /*进入系统*/
    process(&userhead, &flighthead, &recordhead);
    /*清理用户列表*/
    clearUserInfoList(userhead);
    /*清理航班列表*/
    clearFlightInfoList(flighthead);
    /*清理记录列表*/
    clearRecordInfoList(recordhead);
    return 0;
}
 
下面展示一些 `内联代码片`

operation result

first use page
Initial menu interface
admin page
common user page

Guess you like

Origin blog.csdn.net/m0_73804085/article/details/128142264