数据结构课设航班订票系统(C语言版)

数据结构课设航班订票系统(C语言版)

课设要求

(1) 航班管理。每条航线设计出合理的信息,包括:起点和终点站名,航班号,成员额定,飞行周期、飞机型号、余票量、航班票价等
(2) 客户管理。订票的客户信息,包括:姓名,订票数量,身份证,应交的航天票钱。
(3) 系统实现的主要操作和功能。
① 查询航班:根据终点站名输出:航班号、飞机型号、飞行日期、余票数量和仓位信息,航班票价
② 搜索航班:根据乘客提供的信息,输出对应信息的航班,方便乘客订票,以及排队等候订票。
(1)由起点和终点搜索航班:根据乘客输入的起点和终点站信息,输出对应航班的信息。
(2)搜索所有航班:打印出所有航班的信息。
(3)由编号查询航班:根据乘客输入的航班编号,输出该航班的信息。
③ 订票业务:根据用户需求(航班号和订票数量)查询该航班票额情况,若有余票,则为客户办理订票手续,输出座位号,显示应交的航天票钱。如果已满或余票少于订票额,则需要重新询问客户要求。
④ 退票业务:根据客户提供的信息(日期,航班号)为客户办理退票手续,退还其55%的航班票价。
⑤ 录入和删除:
(1)录入:输入航班信息(起点、终点、编号、飞机号、飞行日期、总载客、余票量、航班票价),若该航班不存在,则插入航班,若航班已经存在,就输出信息不正常。
(2)删除:直接输入航班编号,若存在就直接删除,若不存在则提示不存在该航班。

课题的功能模块的划分

功能划分

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

源代码

下面展示 源代码

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

#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;
}
 
下面展示一些 `内联代码片`

运行结果

首次使用页面
初始菜单界面
管理员页面
普通用户页面

猜你喜欢

转载自blog.csdn.net/m0_73804085/article/details/128142264