数据结构:双向链表进行存储,便于增删
若用户文件为空,则初始化用户 账号: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: 编译脚本,定义了编译和链接规则。
编译和运行
-
安装编译器: 确保已安装
gcc
编译器。可以通过以下命令安装(适用于Ubuntu):sh复制代码sudo apt-get update sudo apt-get install gcc
-
编译项目: 在项目根目录(即包含
Makefile
的目录)下运行以下命令:sh 复制代码 make
该命令会编译所有源文件,并将生成的对象文件放在
obj
目录中,最终生成可执行文件main
。 -
运行程序: 编译成功后,在项目根目录下运行:
sh 复制代码 ./main
功能说明
- 用户身份验证: 启动程序后,系统会提示用户输入用户名和密码进行身份验证。
- 菜单选项: 成功登录后,系统会显示主菜单,用户可以选择不同的功能:
- 添加航班
- 显示航班
- 修改航班
- 删除航班
- 排序航班
- 保存数据
- 加载数据
- 退出系统
- 添加航班: 用户可以输入航班号、起始地、目的地、起飞时间、降落时间等信息添加新的航班。
- 显示航班: 系统会列出所有已添加的航班信息。
- 修改航班: 用户可以根据航班号查找并修改特定航班的信息。
- 删除航班: 用户可以根据航班号查找并删除特定航班。
- 排序航班: 系统提供不同的排序方式,如按起飞时间、按降落时间等,对航班信息进行排序。
- 保存数据: 用户可以将当前的航班信息保存到文件中。
- 加载数据: 用户可以从文件中加载之前保存的航班信息。
注意事项
- 数据保存: 每次修改航班信息后,请记得保存数据,以免丢失。
- 用户管理: 默认情况下,系统会包含一个管理员账户,用户可以根据需要添加更多用户。
未来功能
- 图形用户界面: 未来版本可能会引入图形用户界面,使操作更加直观。
- 多用户支持: 未来版本可能会增加多用户同时操作的支持。
希望本用户手册能帮助您顺利使用该航班管理系统。如有任何问题,请参阅项目的文档资料或联系项目维护人员。
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