最详细 <双向链表> 航班管理系统 + Makefile项目管理

在这里插入图片描述

数据结构:双向链表进行存储,便于增删
若用户文件为空,则初始化用户 账号:admin 密码:123

用户手册

运行环境 LinuxC

项目概述

本项目是一个航班管理系统,使用C语言编写,支持添加、显示、修改、删除航班信息,用户身份验证,航班排序,以及从文件中保存和加载数据。

目录结构
hb/
├── doc/
├── inc/
│   ├── flight.h
│   └── ...
├── obj/
├── src/
│   ├── flight.c
│   ├── main.c
│   ├── menu.c
│   ├── pwdMatch.c
│   ├── sortFly.c
│   ├── users.c
│   └── ...
├── Makefile
文件说明
  • doc/: 存放项目的文档资料。

  • inc/
    存放头文件。
    • flight.h: 包含航班相关的函数声明和结构体定义。
  • obj/: 存放编译生成的对象文件。

  • src/
    存放源代码文件。
    • flight.c: 实现航班相关的函数。
    • main.c: 主函数,程序入口。
    • menu.c: 实现菜单显示和处理。
    • pwdMatch.c: 实现用户身份验证。
    • sortFly.c: 实现航班排序功能。
    • users.c: 实现用户管理功能。
  • Makefile: 编译脚本,定义了编译和链接规则。

编译和运行
  1. 安装编译器: 确保已安装 gcc 编译器。可以通过以下命令安装(适用于Ubuntu):

    sh复制代码sudo apt-get update
    sudo apt-get install gcc
    
  2. 编译项目: 在项目根目录(即包含 Makefile 的目录)下运行以下命令:

    sh
    复制代码
    make
    

    该命令会编译所有源文件,并将生成的对象文件放在 obj 目录中,最终生成可执行文件 main

  3. 运行程序: 编译成功后,在项目根目录下运行:

    sh
    复制代码
    ./main
    
功能说明
  1. 用户身份验证: 启动程序后,系统会提示用户输入用户名和密码进行身份验证。
  2. 菜单选项: 成功登录后,系统会显示主菜单,用户可以选择不同的功能:
    • 添加航班
    • 显示航班
    • 修改航班
    • 删除航班
    • 排序航班
    • 保存数据
    • 加载数据
    • 退出系统
  3. 添加航班: 用户可以输入航班号、起始地、目的地、起飞时间、降落时间等信息添加新的航班。
  4. 显示航班: 系统会列出所有已添加的航班信息。
  5. 修改航班: 用户可以根据航班号查找并修改特定航班的信息。
  6. 删除航班: 用户可以根据航班号查找并删除特定航班。
  7. 排序航班: 系统提供不同的排序方式,如按起飞时间、按降落时间等,对航班信息进行排序。
  8. 保存数据: 用户可以将当前的航班信息保存到文件中。
  9. 加载数据: 用户可以从文件中加载之前保存的航班信息。
注意事项
  1. 数据保存: 每次修改航班信息后,请记得保存数据,以免丢失。
  2. 用户管理: 默认情况下,系统会包含一个管理员账户,用户可以根据需要添加更多用户。
未来功能
  1. 图形用户界面: 未来版本可能会引入图形用户界面,使操作更加直观。
  2. 多用户支持: 未来版本可能会增加多用户同时操作的支持。

希望本用户手册能帮助您顺利使用该航班管理系统。如有任何问题,请参阅项目的文档资料或联系项目维护人员。

在这里插入图片描述

flight.h

/**
 * @brief 初始化链表头节点
 * 
 * @return HeadNode* 返回初始化后的头节点指针
 */

#ifndef FLIGHT_H
#define FLIGHT_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <termios.h>
#include <unistd.h>

#define MAX_USERS 10 // 定义最大用户数量

// 航班信息结构体
typedef struct Flight
{
    char number[10];     // 航班号
    char staddress[20];  // 出发地点
    char arraddress[20]; // 到达地点
    char date[20];       // 日期
    char stime[10];      // 出发时间
    char atime[10];      // 到达时间
    float price;         // 票价
    char type[10];       // 类型
} Flight;

// 航班管理双向链表节点信息
typedef struct FlightNode
{
    Flight fly;              // 航班的信息数据
    struct FlightNode *prev; // 前一个节点
    struct FlightNode *next; // 后一个节点
} FlightNode;

// 头节点信息
typedef struct HeadNode
{
    FlightNode *head; // 指向双向链表的头节点
    FlightNode *tail; // 指向双向链表的尾节点
    int numbers;      // 链表中的节点数量
} HeadNode;

// 用户信息结构体
typedef struct User
{
    char username[20]; // 用户名
    char password[20]; // 密码
    int isVip;         // 是否为管理员,1表示管理员,0表示普通用户
} User;

int num_users; // 用户数量

User users[MAX_USERS];

// 航班系统函数声明

/**
 * @brief 初始化链表头节点
 * 
 * @return HeadNode* 返回初始化后的头节点指针
 */
HeadNode *headnode_init();

/**
 * @brief 创建航班节点
 * 
 * @param fly 指向航班信息的指针
 * @return FlightNode* 返回创建的航班节点指针
 */
FlightNode *flight_create(Flight *fly);

/**
 * @brief 添加航班信息到链表尾部
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool addTail_flight(HeadNode *headnode);

/**
 * @brief 删除航班信息
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool delete_flight(HeadNode *headnode);

/**
 * @brief 修改航班信息
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool modify_flight(HeadNode *headnode);

/**
 * @brief 查询航班信息
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool find_flight(HeadNode *headnode);

/**
 * @brief 显示所有航班信息
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool show_flights(HeadNode *headnode);

/**
 * @brief 按航班号升序排序
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool sort_flight_number(HeadNode *headnode);

/**
 * @brief 按出发时间升序排序
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool sort_flight_stime(HeadNode *headnode);

/**
 * @brief 按票价升序排序
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool sort_flight_price(HeadNode *headnode);

/**
 * @brief 显示排序菜单,并执行排序
 * 
 * @param headnode 链表头节点指针
 */
extern void sort_flight(HeadNode *headnode);

/**
 * @brief 保存航班信息到文件
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool save_file(HeadNode *headnode);

/**
 * @brief 清空航班链表
 * 
 * @param headnode 链表头节点指针
 */
extern void clear_flight_list(HeadNode *headnode);

/**
 * @brief 从文件加载航班信息
 * 
 * @param headnode 链表头节点指针
 * @return bool 成功返回true,失败返回false
 */
extern bool load_file(HeadNode *headnode);

/**
 * @brief 显示排序菜单
 */
extern void sort_flight_menu();

/**
 * @brief 显示登录界面
 */
extern void login();

/**
 * @brief 显示管理员登录菜单
 */
extern void admin_login_menu();

/**
 * @brief 管理员操作航班信息
 * 
 * @param head 链表头节点指针
 */
extern void flight_admin(HeadNode *head);

/**
 * @brief 用户操作航班信息
 * 
 * @param head 链表头节点指针
 */
extern void flight_user(HeadNode *head);

/**
 * @brief 模拟获取用户数据而不显示内容
 */
extern int getch();

/**
 * @brief 保存用户数据到文件
 */
bool save_users();

/**
 * @brief 从文件加载用户数据
 */
bool load_users();

/**
 * @brief 添加初始用户数据
 */
void add_initial_users();

/**
 * @brief 添加用户
 */
bool add_user();

/**
 * @brief 删除用户
 */
bool delete_user();

/**
 * @brief 修改用户
 */
bool modify_user();

/**
 * @brief 显示所有用户
 */
void show_users();

/**
 * @brief 用户注册功能
 */
void register_user();

/**
 * @brief 用户管理
 */
void users_manger();

/**
 * @brief 用户管理界面
 */
void users_manger_menu();

/**
 * @brief 主界面
 */
void main_menu();

/**
 * @brief (管理员)功能界面
 */
void admin_user_menu();

/**
 * @brief 检查用户数据文件是否存在
 */
bool file_exists();

/**
 * @brief 用户登录
 * 
 * @param head 链表头节点指针
 * @param users 用户信息数组
 * @return bool 成功返回true,失败返回false
 */
extern bool login_user(HeadNode *head, User users[]);

#endif // FLIGHT_H

flight.c
#include"flight.h"
 
struct HeadNode *headnode_init()
{
    // 为头节点申请空间
    HeadNode *headnode = malloc(sizeof(HeadNode));
    if (headnode == NULL)
        return NULL;
    // 初始化头节点
    headnode->head = NULL;
    headnode->tail = NULL;
    headnode->numbers = 0;

    return headnode;
}

// 初始化双链表节点信息(新节点)
struct FlightNode *flight_create(Flight *fly)
{
    FlightNode *pnew = malloc(sizeof(FlightNode));
    if (pnew == NULL)
        return NULL;

    // 初始化航班信息
    strcpy(pnew->fly.number, fly->number);
    strcpy(pnew->fly.staddress, fly->staddress);
    strcpy(pnew->fly.arraddress, fly->arraddress);
    strcpy(pnew->fly.date, fly->date);
    strcpy(pnew->fly.stime, fly->stime);
    strcpy(pnew->fly.atime, fly->atime);

    pnew->fly.price = fly->price;
    strcpy(pnew->fly.type, fly->type);

    pnew->next = NULL;
    pnew->prev = NULL;
    return pnew;
}

// 1、添加航班信息 (创建链表)
bool addTail_flight(HeadNode *headnode)
{
    Flight pnew;
    printf("请输入航班号:");
    scanf("%s", pnew.number);

    FlightNode *p = headnode->head;
    // 遍历查找航班号是否重复添加
    while (p)
    {
        if (strcmp(p->fly.number, pnew.number) == 0)
        {
            printf("航班号重复!无法添加!\n");
            return false;
        }
        else
            p = p->next;
    }
    printf("请输入起点站: ");
    scanf("%s", pnew.staddress);
    while(getchar()!='\n');
    printf("请输入终点站: ");
    scanf("%s", pnew.arraddress);
    while(getchar()!='\n');
    printf("请输入班期 (格式 2024.12.12 ): ");
    scanf("%s", pnew.date);
    while(getchar()!='\n');
    printf("请输入起飞时间: ");
    scanf("%s", pnew.stime);
    while(getchar()!='\n');
    printf("请输入到达时间: ");
    scanf("%s", pnew.atime);
    while(getchar()!='\n');
    printf("请输入票价: ");
    scanf("%f", &pnew.price);
    while(getchar()!='\n');
    printf("请输入机型(空客A320/波音737/国产大飞机C919): ");
    scanf("%s", pnew.type);

    FlightNode *newNode = flight_create(&pnew);
    if (newNode == NULL)
        return false;

    // 从无到有
    if (headnode->head == NULL)
    {
        headnode->head = newNode;
        headnode->tail = newNode;
        newNode->prev = headnode->head;
    }
    // 从少到多-尾插法
    else
    {
        newNode->prev = headnode->tail;
        headnode->tail->next = newNode;
        headnode->tail = newNode;
    }
    headnode->numbers++;
    printf("添加成功\n");
    return true;
}

// 2、删除航班信息
bool delete_flight(HeadNode *headnode)
{
    FlightNode *p = headnode->head;
    if (p == NULL)
    {
        printf("暂无航班信息!");
        return false;
    }

    char number[10]; // 航班号
    printf("请输入要删除的航班信息的航班号:");
    scanf("%s", number);
    while (p)
    {
        if (strcmp(p->fly.number, number) == 0)
            break;
        else
            p = p->next;
    }

    if (p == NULL)
    {
        printf("暂无匹配的航班信息,删除失败!\n");
        return false;
    }

    if (headnode->head == p) // 首节点
    {
        headnode->head = p->next;

        p->next = NULL;
        p->prev = NULL;
        free(p);
    }
    else if (headnode->tail == p) // 尾节点
    {
        headnode->tail = p->prev;
        p->prev->next = NULL;
        p->prev = NULL;
        free(p);
    }
    else // 中间节点
    {
        p->prev->next = p->next;
        p->next->prev = p->prev;
        p->next = NULL;
        p->prev = NULL;
        free(p);
    }

    headnode->numbers--;

    printf("航班信息删除成功\n");

    return true;
}

// 3、修改航班信息
bool modify_flight(HeadNode *headnode)
{
    FlightNode *p = headnode->head;
    if (p == NULL)
    {
        printf("暂无航班信息!");
        return false;
    }

    Flight pnew;
    printf("请输入要修改的航班号:");
    scanf("%s", pnew.number);

    // 遍历查找航班号
    while (p)
    {
        if (strcmp(p->fly.number, pnew.number) == 0)
        {
            printf("修改开始\n");
            printf("请修改航班号:");
            scanf("%s", pnew.number);
            printf("请修改起点站: ");
            scanf("%s", pnew.staddress);
            printf("请修改终点站: ");
            scanf("%s", pnew.arraddress);
            printf("请修改班期 (格式 2024.12.12 ): ");
            scanf("%s", pnew.date);
            printf("请修改起飞时间: ");
            scanf("%s", pnew.stime);
            printf("请修改到达时间: ");
            scanf("%s", pnew.atime);
            printf("请修改票价: ");
            scanf("%f", &pnew.price);
            printf("请修改机型(空客A320/波音737/国产大飞机C919): ");
            scanf("%s", pnew.type);

            strcpy(p->fly.number, pnew.number);
            strcpy(p->fly.staddress, pnew.staddress);
            strcpy(p->fly.arraddress, pnew.arraddress);
            strcpy(p->fly.date, pnew.date);
            strcpy(p->fly.stime, pnew.stime);
            strcpy(p->fly.atime, pnew.atime);
            p->fly.price = pnew.price;
            strcpy(p->fly.type, pnew.type);

            return true;
        }
        else
            p = p->next;
    }
    printf("无此航班信息!");
    return false;
}

// 4、按航班号查询航班信息
bool find_flight(HeadNode *headnode)
{
    FlightNode *p = headnode->head;
    if (p == NULL)
        return false;

    Flight pnew;
    printf("请输入待查询航班号:\n");
    scanf("%s", pnew.number);
    while (p)
    {
        if (strcmp(p->fly.number, pnew.number) == 0)
        {
            printf("航班号\t起点站\t终点站\t班期\t\t起飞时间\t到达时间\t票价\t\t机型\n");

            printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\t¥%.2f\t%s", p->fly.number, p->fly.staddress, p->fly.arraddress, p->fly.date,
                   p->fly.stime, p->fly.atime, p->fly.price, p->fly.type);
            printf("\n");
            return true;
        }
        else
            p = p->next;
    }

    printf("暂无此航班!\n");
    return false;
}

// 5、显示所有航班信息
bool show_flights(HeadNode *headnode)
{
    FlightNode *p = headnode->head;
    if (p == NULL)
    {
        printf("暂无航班信息!\n");
        return false;
    }
    printf("航班号\t起点站\t终点站\t班期\t\t起飞时间\t到达时间\t票价\t\t机型\n");
    while (p)
    {
        printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\t¥%.2f\t%s", p->fly.number, p->fly.staddress, p->fly.arraddress, 
                                        p->fly.date, p->fly.stime, p->fly.atime, p->fly.price, p->fly.type);
        p = p->next;
        printf("\n");
    }
    printf("\n");
    return true;
}


// 7. 保存航班信息到文件
bool save_file(HeadNode *headnode)
{
    FILE *fd = fopen("flights.txt", "w+");
    if (fd == NULL)
    {
        printf("无法打开文件 %s\n", "flights.txt");
        return false;
    }

    FlightNode *p = headnode->head;
    while (p)
    {
        fprintf(fd, "%s %s %s %s %s %s %.2f %s\n", p->fly.number, p->fly.staddress, p->fly.arraddress, p->fly.date,
                p->fly.stime, p->fly.atime, p->fly.price, p->fly.type);
        p = p->next;
    }

    fclose(fd);
    printf("航班信息已成功保存到文件 %s\n", "flights.txt");
    return true;
}

// 清空链表的函数
void clear_flight_list(HeadNode *headnode)
{
    FlightNode *cur = headnode->head;
    while (cur != NULL)
    {
        FlightNode *next = cur->next;
        free(cur);
        cur = next;
    }
    headnode->head = NULL;
    headnode->tail = NULL;
    headnode->numbers = 0;
}

// 8. 从文件加载航班信息
bool load_file(HeadNode *headnode)
{
    // 清空现有链表
    clear_flight_list(headnode);
    FILE *fd = fopen("flights.txt", "r");
    if (fd == NULL)
    {
        printf("文件 %s 不存在,将创建新文件\n", "flights.txt");
        fd = fopen("flights.txt", "w");
        if (fd == NULL)
        {
            printf("无法创建文件 %s\n", "flights.txt");
            return false;
        }
        fclose(fd);
        return true;
    }

    while (true)
    {
        Flight pnew;
        int res = fscanf(fd, "%s %s %s %s %s %s %f %s", pnew.number, pnew.staddress, pnew.arraddress, pnew.date,
                         pnew.stime, pnew.atime, &pnew.price, pnew.type);
        if (res == EOF)
        {
            break;
        }

        FlightNode *newNode = flight_create(&pnew);
        if (headnode->head == NULL)
        {
            headnode->head = newNode;
            headnode->tail = newNode;
            newNode->prev = headnode->head;
        }
        else
        {
            newNode->prev = headnode->tail;
            headnode->tail->next = newNode;
            headnode->tail = newNode;
        }
        headnode->numbers++;
    }

    fclose(fd);
    printf("航班信息已成功从文件 %s 加载\n", "flights");
    return true;
}






// 航班系统 (管理员)
void flight_admin(HeadNode *head)
{
    while (1)
    {
        admin_login_menu();
        printf("请选择相应序号:\n");
        int input;
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            return;
        case 1:
            // 1、添加航班信息
            addTail_flight(head);
            break;
        case 2:

            // 2、删除航班信息
            delete_flight(head);
            break;
        case 3:
            // 3、修改航班信息
            modify_flight(head);
            break;
        case 4:

            // 4、查询航班信息
            find_flight(head);
            break;
        case 5:
            show_flights(head);
            // 5、显示全部航班信息
            break;
        case 6:
            // 6、排序航班信息
            sort_flight(head);
            break;
        case 7:
            // 7、保存航班信息
            save_file(head);
            break;
        case 8:
            //添加用户
            users_manger();
        default:
            printf("输入错误,请重新输入\n");
            break;
        }
    }
}

// 航班系统 (用户)
void flight_user(HeadNode *head)
{
    while (1)
    {
        admin_user_menu();
        printf("请选择相应序号:\n");
        int input;
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            return;
        case 1:
            show_flights(head);
            // 1、显示所有航班信息
            break;
        case 2:
            // 2、查询航班信息
            find_flight(head);
            break;
        case 3:
            // 3、排序航班信息
            sort_flight(head);
            break;

        default:
            printf("输入错误,请重新输入!\n");
            break;
        }
    }
}
menu.c
/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2024-08-07 19:49:51
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2024-08-07 21:03:41
 * @FilePath: \Share\项目一\hb\src\menu.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include"flight.h"

void main_menu() 
{
    printf("|—————————————————————————————————————————————————|\n");
    printf("|                 航班系统登录界面                 |\n");
    printf("|—————————————————————————————————————————————————|\n");
    printf("|                1. 用户登录                      |\n");
    printf("|                2. 用户注册                      |\n");
    printf("|                0. 退出系统                      |\n");
    printf("|—————————————————————————————————————————————————|\n");
}

// 排序航班信息界面
void sort_flight_menu()
{
    printf("|—————————————————————————————————————————————————|\n");
    printf("|                 航班信息排序系统                 |\n");
    printf("|—————————————————————————————————————————————————|\n");
    printf("|                1.按航班号升序                    |\n");
    printf("|                2.按起飞时间升序                  |\n");
    printf("|                3.按价格升序                      |\n");
    printf("|                0.退出排序系统                    |\n");
    printf("|—————————————————————————————————————————————————|\n");
}


// (管理员)功能界面
void admin_login_menu()
{
    printf("        航班管理系统(管理员)        \n");
    printf("------------------------------------\n");
    printf("|1、添加航班信息                     |\n");
    printf("|2、删除航班信息                     |\n");
    printf("|3、修改航班信息                     |\n");
    printf("|4、查询航班信息                     |\n");
    printf("|5、显示全部航班信息                  |\n");
    printf("|6、排序航班                         |\n");
    printf("|7、保存航班信息                     |\n");
    printf("|8、用户管理                        |\n");
    printf("|0、退出                            |\n");
    printf("------------------------------------\n");
}

// (用户)功能界面
void admin_user_menu()
{
    printf("        航班管理系统(普通用户)      \n");
    printf("------------------------------------\n");
    printf("|1、显示所有航班信息                |\n");
    printf("|2、查询航班信息                    |\n");
    printf("|3、排序航班信息                    |\n");
    printf("|0、退出                            |\n");
    printf("------------------------------------\n");
}

//用户管理界面
void users_manger_menu() 
{
    printf("|—————————————————————————————————————————————————|\n");
    printf("|                  用户管理系统                    |\n");
    printf("|—————————————————————————————————————————————————|\n");
    printf("|                1. 用户添加                      |\n");
    printf("|                2. 删除用户                      |\n");
    printf("|                3. 修改用户                      |\n");
    printf("|                4. 显示所有用户                  |\n");
    printf("|                0. 退出系统                      |\n");
    printf("|—————————————————————————————————————————————————|\n");
}
pwdMatch.c
#include "flight.h"


// 模拟获取用户输入而不显示字符
int getch() {
    struct termios oldt, newt;
    int ch;
    tcgetattr(STDIN_FILENO, &oldt);           // 获取终端属性
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);         // 禁用缓冲和回显
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);  // 设置终端属性
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);  // 恢复终端属性
    return ch;
}

// 登录验证
bool login_user(HeadNode *head, User users[]) 
{
    if (num_users == 0) 
    {
        printf("\n暂无用户!\n");
        return false;
    }

    char username[20];
    char password[20];

    printf("请输入用户名: ");
    scanf("%s", username);
    while (getchar()!='\n');    //清空缓冲区
    printf("请输入密码: ");

    int i = 0;
    char ch;
    while ((ch = getch()) != '\n' && i < 19) 
    { // 使用getch()读取单个字符,直到按下回车键或输入长度达到上限
        if (ch == 127 || ch == '\b') 
        { // 检测退格键(127是delete键的ASCII码)
            if (i > 0) 
            {
                printf("\b \b"); // 删除一个字符并回退光标
                i--;
            }
        } else 
        {
            password[i++] = ch;
            printf("*"); // 显示星号以表示输入的字符
        }
    }
    password[i] = '\0'; // 添加字符串结束标志
    printf("\n"); // 换行符

    for (int i = 0; i < num_users; i++) 
    {
        if (strcmp(users[i].username, username) == 0 && strcmp(users[i].password, password) == 0) 
        {
            if (users[i].isVip == 0) 
            {
                printf("\n用户登陆成功!\n");
                flight_user(head);
            } 
            else 
            {
                printf("\n管理员登陆成功!\n");
                flight_admin(head);
            }
            return true;
        }
    }

    printf("\n无此用户!\n");
    return false;
}

sortFly.c
#include"flight.h"

// 6.1按航班号升序排序-插入排序
bool sort_flight_number(HeadNode *headnode)
{
    if (headnode == NULL || headnode->head == NULL || headnode->head->next == NULL)
    {
        printf("暂无航班信息或无需排序!\n");
        return false;
    }

    FlightNode *i, *j;
    char temp_number[10];
    char temp_staddress[20];
    char temp_arraddress[20];
    char temp_date[10];
    char temp_stime[10];
    char temp_atime[10];
    float temp_price;
    char temp_type[10];

    for (i = headnode->head; i->next != NULL; i = i->next)
    {
        for (j = i->next; j != NULL; j = j->next)
        {
            if (strcmp(i->fly.number, j->fly.number) > 0)
            {
                // 交换航班号
                strcpy(temp_number, i->fly.number);
                strcpy(i->fly.number, j->fly.number);
                strcpy(j->fly.number, temp_number);

                // 交换起点站
                strcpy(temp_staddress, i->fly.staddress);
                strcpy(i->fly.staddress, j->fly.staddress);
                strcpy(j->fly.staddress, temp_staddress);

                // 交换终点站
                strcpy(temp_arraddress, i->fly.arraddress);
                strcpy(i->fly.arraddress, j->fly.arraddress);
                strcpy(j->fly.arraddress, temp_arraddress);

                // 交换班期
                strcpy(temp_date, i->fly.date);
                strcpy(i->fly.date, j->fly.date);
                strcpy(j->fly.date, temp_date);

                // 交换起飞时间
                strcpy(temp_stime, i->fly.stime);
                strcpy(i->fly.stime, j->fly.stime);
                strcpy(j->fly.stime, temp_stime);

                // 交换到达时间
                strcpy(temp_atime, i->fly.atime);
                strcpy(i->fly.atime, j->fly.atime);
                strcpy(j->fly.atime, temp_atime);

                // 交换票价
                temp_price = i->fly.price;
                i->fly.price = j->fly.price;
                j->fly.price = temp_price;

                // 交换机型
                strcpy(temp_type, i->fly.type);
                strcpy(i->fly.type, j->fly.type);
                strcpy(j->fly.type, temp_type);
            }
        }
    }
    show_flights(headnode);
    printf("航班信息按航班号升序排序完成!\n");
    return true;
}

// 6.2按起飞时间升序
bool sort_flight_stime(HeadNode *headnode)
{
    if (headnode == NULL || headnode->head == NULL || headnode->head->next == NULL)
    {
        printf("暂无航班信息或无需排序!\n");
        return false;
    }

    FlightNode *sort = NULL;          // 已排序部分
    FlightNode *cur = headnode->head; // 当前节点
    while (cur != NULL)
    {
        FlightNode *next = cur->next; // 记录下一节点

        // 找到插入位置
        if (sort == NULL || strcmp(cur->fly.stime, sort->fly.stime) <= 0)
        {
            // 插入到已排序部分的头部
            cur->next = sort;
            if (sort != NULL)
                sort->prev = cur;
            sort = cur;
            sort->prev = NULL;
        }
        // 在已排序链表中找到插入位置
        else
        {
            FlightNode *temp = sort;
            while (temp->next != NULL && strcmp(cur->fly.stime, temp->next->fly.stime) > 0)
            {
                temp = temp->next;
            }
            cur->next = temp->next;
            if (temp->next != NULL)
            {
                temp->next->prev = cur;
            }

            temp->next = cur;
            cur->prev = temp;
        }

        cur = next; // 移动到下一个节点
    }
    headnode->head = sort; // 更新头节点
    printf("航班信息按起飞时间升序排序完成!\n");
    show_flights(headnode);
    return true;
}

// 6.3 按价格升序排序(双链表 - 冒泡排序)
bool sort_flight_price(HeadNode *headnode)
{
    // 检查头节点是否为空或者链表中只有一个节点
    if (headnode == NULL || headnode->head == NULL || headnode->head->next == NULL)
        return true;

    FlightNode *i, *j;

    for (i = headnode->head; i != NULL; i = i->next)
    {
        for (j = headnode->head; j->next != NULL; j = j->next)
        {
            // 如果前一个节点价格大于后一个节点,则交换它们
            if (j->fly.price > j->next->fly.price)
            {
                // 交换节点内容(不交换节点本身,而是交换节点的航班数据)
                Flight temp = j->fly;
                j->fly = j->next->fly;
                j->next->fly = temp;
            }
        }
    }
    printf("航班信息按价格升序排序完成!\n");
    show_flights(headnode);
    return true; // 排序成功
}

// 6、排序航班信息
void sort_flight(HeadNode *headnode)
{
    sort_flight_menu();
    int input;
    printf("请对应序号选择需要查询的信息:");
    scanf("%d", &input);

    switch (input)
    {
    case 0:
        printf("已退出航班信息排序系统\n");
        return;
    case 1:
        sort_flight_number(headnode); // 1.按航班号升序
        break;
    case 2:
        sort_flight_stime(headnode); // 2.按起飞时间升序
        break;
    case 3:
        sort_flight_price(headnode); // 3.按价格升序
        break;
    default:
        printf("输入错误,请重新输入\n");
        break;
    }
}
users.c
#include"flight.h"

// 6.1按航班号升序排序-插入排序
bool sort_flight_number(HeadNode *headnode)
{
    if (headnode == NULL || headnode->head == NULL || headnode->head->next == NULL)
    {
        printf("暂无航班信息或无需排序!\n");
        return false;
    }

    FlightNode *i, *j;
    char temp_number[10];
    char temp_staddress[20];
    char temp_arraddress[20];
    char temp_date[10];
    char temp_stime[10];
    char temp_atime[10];
    float temp_price;
    char temp_type[10];

    for (i = headnode->head; i->next != NULL; i = i->next)
    {
        for (j = i->next; j != NULL; j = j->next)
        {
            if (strcmp(i->fly.number, j->fly.number) > 0)
            {
                // 交换航班号
                strcpy(temp_number, i->fly.number);
                strcpy(i->fly.number, j->fly.number);
                strcpy(j->fly.number, temp_number);

                // 交换起点站
                strcpy(temp_staddress, i->fly.staddress);
                strcpy(i->fly.staddress, j->fly.staddress);
                strcpy(j->fly.staddress, temp_staddress);

                // 交换终点站
                strcpy(temp_arraddress, i->fly.arraddress);
                strcpy(i->fly.arraddress, j->fly.arraddress);
                strcpy(j->fly.arraddress, temp_arraddress);

                // 交换班期
                strcpy(temp_date, i->fly.date);
                strcpy(i->fly.date, j->fly.date);
                strcpy(j->fly.date, temp_date);

                // 交换起飞时间
                strcpy(temp_stime, i->fly.stime);
                strcpy(i->fly.stime, j->fly.stime);
                strcpy(j->fly.stime, temp_stime);

                // 交换到达时间
                strcpy(temp_atime, i->fly.atime);
                strcpy(i->fly.atime, j->fly.atime);
                strcpy(j->fly.atime, temp_atime);

                // 交换票价
                temp_price = i->fly.price;
                i->fly.price = j->fly.price;
                j->fly.price = temp_price;

                // 交换机型
                strcpy(temp_type, i->fly.type);
                strcpy(i->fly.type, j->fly.type);
                strcpy(j->fly.type, temp_type);
            }
        }
    }
    show_flights(headnode);
    printf("航班信息按航班号升序排序完成!\n");
    return true;
}

// 6.2按起飞时间升序
bool sort_flight_stime(HeadNode *headnode)
{
    if (headnode == NULL || headnode->head == NULL || headnode->head->next == NULL)
    {
        printf("暂无航班信息或无需排序!\n");
        return false;
    }

    FlightNode *sort = NULL;          // 已排序部分
    FlightNode *cur = headnode->head; // 当前节点
    while (cur != NULL)
    {
        FlightNode *next = cur->next; // 记录下一节点

        // 找到插入位置
        if (sort == NULL || strcmp(cur->fly.stime, sort->fly.stime) <= 0)
        {
            // 插入到已排序部分的头部
            cur->next = sort;
            if (sort != NULL)
                sort->prev = cur;
            sort = cur;
            sort->prev = NULL;
        }
        // 在已排序链表中找到插入位置
        else
        {
            FlightNode *temp = sort;
            while (temp->next != NULL && strcmp(cur->fly.stime, temp->next->fly.stime) > 0)
            {
                temp = temp->next;
            }
            cur->next = temp->next;
            if (temp->next != NULL)
            {
                temp->next->prev = cur;
            }

            temp->next = cur;
            cur->prev = temp;
        }

        cur = next; // 移动到下一个节点
    }
    headnode->head = sort; // 更新头节点
    printf("航班信息按起飞时间升序排序完成!\n");
    show_flights(headnode);
    return true;
}

// 6.3 按价格升序排序(双链表 - 冒泡排序)
bool sort_flight_price(HeadNode *headnode)
{
    // 检查头节点是否为空或者链表中只有一个节点
    if (headnode == NULL || headnode->head == NULL || headnode->head->next == NULL)
        return true;

    FlightNode *i, *j;

    for (i = headnode->head; i != NULL; i = i->next)
    {
        for (j = headnode->head; j->next != NULL; j = j->next)
        {
            // 如果前一个节点价格大于后一个节点,则交换它们
            if (j->fly.price > j->next->fly.price)
            {
                // 交换节点内容(不交换节点本身,而是交换节点的航班数据)
                Flight temp = j->fly;
                j->fly = j->next->fly;
                j->next->fly = temp;
            }
        }
    }
    printf("航班信息按价格升序排序完成!\n");
    show_flights(headnode);
    return true; // 排序成功
}

// 6、排序航班信息
void sort_flight(HeadNode *headnode)
{
    sort_flight_menu();
    int input;
    printf("请对应序号选择需要查询的信息:");
    scanf("%d", &input);

    switch (input)
    {
    case 0:
        printf("已退出航班信息排序系统\n");
        return;
    case 1:
        sort_flight_number(headnode); // 1.按航班号升序
        break;
    case 2:
        sort_flight_stime(headnode); // 2.按起飞时间升序
        break;
    case 3:
        sort_flight_price(headnode); // 3.按价格升序
        break;
    default:
        printf("输入错误,请重新输入\n");
        break;
    }
}
main.c
// main.c
#include "flight.h"

int main()
{   
    
    HeadNode *head = headnode_init(); // 初始化头节点
    if (head == NULL)
    {
        printf("初始化头节点失败!\n");
        return -1;
    }

    
    load_file(head); // 加载航班信息

    // 检查用户数据文件是否存在
    if (file_exists()) 
    {
        load_users();    // 加载用户信息
    } 
    else 
    {
        add_initial_users();    // 初始化用户
        save_users();           // 保存初始用户数据
    }

    while (1) {
        main_menu();
        int choice;
        printf("请选择操作: ");
        scanf("%d", &choice);
        switch (choice) {
            case 1:
                login_user(head,users);
                break;
            case 2:
                register_user();
                break;
            case 3:
                delete_user();
                break;
            case 4:
                modify_user();
                break;
            case 5:
                show_users();
                break;
            case 0:
                save_file(head);    //保存航班信息
                save_users();       //保存用户信息
                printf("系统已退出!\n");
                return 0;
            default:
                printf("输入错误,请重新选择!\n");
                break;
        }
    }

    return 0;
}

Makefile
# 目标文件夹
OBJ_DIR = obj

# 源文件夹
SRC_DIR = src

# 包含文件夹
INC_DIR = inc

# 编译器
CC = gcc

# 编译选项
CFLAGS = -Wall -I$(INC_DIR)

# 源文件
SRCS = $(wildcard $(SRC_DIR)/*.c)

# 对象文件
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))

# 可执行文件
TARGET = main

# 默认目标
all: $(TARGET)

# 链接目标
$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^

# 编译目标
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
	@mkdir -p $(OBJ_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

# 清理
clean:
	rm -f $(OBJ_DIR)/*.o $(TARGET)

.PHONY: all clean
flight.txt
A0001 俄罗斯 小日本 2024.12.26 12:09 15:09 444.00 中国C919
A0005 岳阳 芝加哥 2024.12.11 12:12 12:11 890.00 中国C919
A0004 义务 明斯克 2020.12.08 12:00 13:00 1299.00 波音737
A0006 岳阳 伦敦 2024.12.12 12:00 21:00 1980.00 空客A320
A0003 凤凰 巴黎 2024.11.11 1:00 18:00 1999.00 中国C919
users.txt
admin 123 1
user 123 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值