开发环境
- 操作系统:Windows 11专业版
- 开发工具:Visual Studio Code
- 编程语言:C
项目考核验收表
1. 设计目标
本项目的目标是设计并实现一个简易的航班管理系统。该系统应具备以下功能:
- 添加航班信息
- 查询航班信息
- 显示所有航班信息
- 修改航班信息
- 删除航班信息
- 对航班信息进行排序
- 保存和加载航班信息
- 用户管理,包括管理员和普通用户两种类型
- 登录功能
2. 功能描述
系统功能包括以下几点:
- 用户管理:管理员可以添加新用户,并进行用户权限的设置(管理员或普通用户)。
- 航班管理:管理员可以添加、修改、删除航班信息,普通用户可以查看和查询航班信息。
- 数据存储:系统支持将航班信息和用户信息保存到文件,并从文件加载数据。
- 排序功能:用户可以根据起飞时间或价格对航班进行排序。
3. 设计方案
系统采用模块化设计,主要功能分为以下几个模块:
- 用户模块:包含用户登录、用户添加等功能。
- 航班模块:包含航班信息的增删改查、排序等功能。
- 文件模块:负责数据的保存和加载。
- 菜单模块:根据用户类型显示不同的功能菜单。
4. 系统框架
系统框架图示如下:
+---------------------+
| Main |
| - 初始化用户数据 |
| - 加载文件数据 |
| - 调用登录函数 |
+---------+-----------+
|
v
+---------------------+
| Login |
| - 输入用户名和密码|
| - 验证用户身份 |
| - 调用菜单函数 |
+---------+-----------+
|
v
+---------------------+
| Menu |
| - 显示功能菜单 |
| - 根据用户选择调用|
| 相应的功能模块 |
+---------+-----------+
|
v
+---------------------+
| Flight |
| - 添加航班信息 |
| - 修改航班信息 |
| - 删除航班信息 |
| - 查询航班信息 |
| - 显示航班信息 |
| - 航班信息排序 |
+---------+-----------+
|
v
+---------------------+
| File |
| - 保存数据到文件 |
| - 从文件加载数据 |
+---------------------+
5. 实现过程
- 功能规划:确定系统需要实现的各项功能,并进行模块划分。
- 代码编写:
- 实现用户管理功能,包括登录验证和用户添加。
- 实现航班管理功能,包括增删改查和排序。
- 实现数据的保存和加载功能。
- 测试与调试:对各个功能模块进行单元测试,发现并修复存在的bug。
- 集成测试:将所有功能模块集成在一起,进行整体测试,确保系统各部分协同工作。
6. 心得体会
通过本次项目的设计和实现,我对C语言的应用有了更深的理解,特别是在结构体、文件操作和字符串处理等方面的应用。此外,在实际开发过程中,我体会到模块化设计的重要性,它不仅让代码更易于管理和维护,也使得功能扩展变得更加方便。遇到的最大挑战是处理用户输入和文件操作部分,这也促使我深入学习相关的知识,提升了编程能力。
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#define MAX_FLIGHTS 100 // 定义最大航班数量
#define MAX_USERS 10 // 定义最大用户数量
static int flight_num = 0; // 当前航班的数量
static int user_num = 0; // 当前用户的数量
typedef struct airplane
{
char number[10]; // 航班号
char Start_City[20]; // 起飞城市
char End_City[20]; // 到达城市
char Start_Time[20]; // 起飞时间
char End_Time[20]; // 到达时间
float Price; // 机票价格
float Discount; // 机票折扣
int Tickets; // 机票剩余数量
} Plane;
typedef struct user
{
char name[20]; // 用户名
char password[20]; // 密码
int isAdmin; // 用户类型 0普通用户 1管理员
} User;
Plane flights[MAX_FLIGHTS]; // 存储航班信息的数组
User users[MAX_USERS]; // 存储用户信息的数组
void Menu(int isAdmin); // 菜单
void addFlight(); // 添加
void findFlight(); // 查询
void displayFlights(); // 显示所有
void modifyFlight(); // 修改
void deleteFlight(); // 删除
void Sort(); // 排序
void saveToFile(); // 保存到文件
void loadFromFile(); // 从文件加载
void addUser(); // 添加用户
/*
功能: 显示菜单信息
参数: isAdmin - 是否管理员
返回值:无
*/
void Menu(int isAdmin)
{
int choice;
loadFromFile(); // 启动时从文件加载数据
while (1)
{
if (isAdmin)
{
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");
}
else
{
printf(" 航班管理系统(普通用户) \n");
printf("------------------------------------\n");
printf("|1、显示所有航班信息 |\n");
printf("|2、查询航班信息 |\n");
printf("|3、排序航班信息 |\n");
printf("|0、退出 |\n");
printf("------------------------------------\n");
}
printf("请输入相应的序号选择! \n");
scanf("%d", &choice);
getchar();
switch (choice)
{
case 1:
displayFlights();
break;
case 2:
findFlight();
break;
case 3:
Sort();
break;
case 4:
if (isAdmin)
addFlight();
else
printf("无权限访问该功能!\n");
break;
case 5:
if (isAdmin)
modifyFlight();
else
printf("无权限访问该功能!\n");
break;
case 6:
if (isAdmin)
deleteFlight();
else
printf("无权限访问该功能!\n");
break;
case 7:
if (isAdmin)
saveToFile();
else
printf("无权限访问该功能!\n");
break;
case 8:
if (isAdmin)
addUser();
else
printf("无权限访问该功能!\n");
break;
case 0:
saveToFile(); // 退出前保存数据
exit(0);
break;
default:
printf("无效的选择,请重试!\n");
}
// 暂停操作
printf("\n");
system("pause"); // 这行代码会使程序等待用户按下任意键
system("cls"); // 清屏操作
}
}
/*
功能: 添加航班信息
参数: 无
返回值:无
*/
void addFlight()
{
if (flight_num >= MAX_FLIGHTS)
{
printf("无法添加更多航班,已达到最大限制!\n");
return;
}
Plane newFlight;
printf("请输入航班号: ");
gets(newFlight.number);
printf("请输入起飞城市: ");
gets(newFlight.Start_City);
printf("请输入到达城市: ");
gets(newFlight.End_City);
printf("请输入起飞时间: ");
gets(newFlight.Start_Time);
printf("请输入到达时间: ");
gets(newFlight.End_Time);
printf("请输入机票价格: ");
scanf("%f", &newFlight.Price);
getchar();
printf("请输入机票折扣: ");
scanf("%f", &newFlight.Discount);
getchar();
printf("请输入剩余票数: ");
scanf("%d", &newFlight.Tickets);
getchar();
flights[flight_num++] = newFlight; // 将新航班添加到数组中
printf("航班添加成功!\n");
}
/*
功能: 显示所有航班信息
参数: 无
返回值:无
*/
void displayFlights()
{
if (flight_num == 0)
{ // 检查是否有航班信息
printf("没有可显示的航班信息!\n");
return;
}
printf("航班号\t\t起飞城市\t到达城市\t起飞时间\t\t到达时间\t\t机票价格\t优惠折扣\t剩余票数\n");
for (int i = 0; i < flight_num; i++)
{
printf("%s\t\t%s\t\t%s\t\t%s\t%s\t%.2f\t\t%.2f\t\t%d\n",
flights[i].number, flights[i].Start_City, flights[i].End_City,
flights[i].Start_Time, flights[i].End_Time,
flights[i].Price, flights[i].Discount, flights[i].Tickets);
}
}
/*
功能: 查询航班信息
参数: 无
返回值:无
*/
void findFlight()
{
if (flight_num == 0)
{ // 检查是否有航班信息
printf("没有可查询的航班信息!\n");
return;
}
char fnum[10];
printf("请输入要查询的航班号:");
fgets(fnum, sizeof(fnum), stdin);
fnum[strcspn(fnum, "\n")] = '\0'; // 去除换行符
for (int i = 0; i < flight_num; i++)
{
if (strcmp(fnum, flights[i].number) == 0)
{
printf("航班号\t\t起飞城市\t到达城市\t起飞时间\t\t到达时间\t\t机票价格\t优惠折扣\t剩余票数\n");
printf("%s\t\t%s\t\t%s\t\t%s\t%s\t%.2f\t\t%.2f\t\t%d\n",
flights[i].number, flights[i].Start_City, flights[i].End_City,
flights[i].Start_Time, flights[i].End_Time,
flights[i].Price, flights[i].Discount, flights[i].Tickets);
return;
}
}
printf("未找到该航班!\n");
}
/*
功能: 修改航班信息
参数: 无
返回值:无
*/
void modifyFlight()
{
if (flight_num == 0)
{ // 检查是否有航班信息
printf("没有修改的航班信息!\n");
return;
}
printf("请输入要修改的航班号:");
char fnum[10];
int flag = 0;
fgets(fnum, 10, stdin);
fnum[strcspn(fnum, "\n")] = 0; // 去掉换行符
for (int i = 0; i < flight_num; i++)
{
if (strcmp(fnum, flights[i].number) == 0)
{
flag = 1;
printf("修改开始\n请输入航班号: ");
gets(flights[i].number);
printf("请输入起飞城市: ");
gets(flights[i].Start_City);
printf("请输入到达城市: ");
gets(flights[i].End_City);
printf("请输入起飞时间: ");
gets(flights[i].Start_Time);
printf("请输入到达时间: ");
gets(flights[i].End_Time);
printf("请输入机票价格: ");
scanf("%f", &flights[i].Price);
getchar();
printf("请输入机票折扣: ");
scanf("%f", &flights[i].Discount);
getchar();
printf("请输入剩余票数: ");
scanf("%d", &flights[i].Tickets);
getchar();
printf("航班修改成功!\n");
break;
}
}
if (flag == 0)
{
printf("未找到该航班号对应的航班信息!\n");
}
}
/*
功能: 删除航班信息
参数: 无
返回值:无
*/
void deleteFlight()
{
if (flight_num == 0)
{ // 检查是否有航班信息
printf("没有可删除的航班信息!\n");
return;
}
printf("请输入要删除的航班号:");
char fnum[10];
int flag = 0;
fgets(fnum, sizeof(fnum), stdin);
fnum[strcspn(fnum, "\n")] = 0;
for (int i = 0; i < flight_num; i++)
{
if (strcmp(fnum, flights[i].number) == 0)
{
flag = 1;
for (int j = i; j < flight_num - 1; j++)
{
flights[j] = flights[j + 1];
}
flight_num--;
printf("航班删除成功!\n");
break;
}
}
if (flag == 0)
{
printf("未找到该航班号对应的航班信息!\n");
}
}
/*
功能: 排序航班信息
参数: 无
返回值:无
*/
void Sort()
{
if (flight_num == 0)
{
printf("没有航班信息可供排序!\n");
return;
}
int choice;
printf("请选择排序方式:\n1.按起飞时间升序\n2.按价格升序\n");
scanf("%d", &choice);
getchar();
if (choice == 1)
{
// 按起飞时间升序排序
for (int i = 0; i < flight_num - 1; i++)
{
for (int j = 0; j < flight_num - i - 1; j++)
{
if (strcmp(flights[j].Start_Time, flights[j + 1].Start_Time) > 0)
{
Plane temp = flights[j];
flights[j] = flights[j + 1];
flights[j + 1] = temp;
}
}
}
printf("航班信息已按起飞时间升序排序!\n");
}
else if (choice == 2)
{
// 按价格升序排序
for (int i = 0; i < flight_num - 1; i++)
{
for (int j = 0; j < flight_num - i - 1; j++)
{
if (flights[j].Price > flights[j + 1].Price)
{
Plane temp = flights[j];
flights[j] = flights[j + 1];
flights[j + 1] = temp;
}
}
}
printf("航班信息已按价格升序排序!\n");
}
else
{
printf("无效的选择,请重试!\n");
}
}
/*
功能: 保存航班信息到文件
参数: 无
返回值:无
*/
/*
功能: 保存航班信息到文件
参数: 无
返回值:无
*/
void saveToFile()
{
FILE *file = fopen("flights.txt", "wb");
if (file == NULL)
{
printf("无法打开文件进行写入!\n");
return;
}
fwrite(&flight_num, sizeof(int), 1, file); // 先保存航班数量
fwrite(flights, sizeof(Plane), flight_num, file); // 再保存航班信息
fwrite(&user_num, sizeof(int), 1, file); // 保存用户数量
fwrite(users, sizeof(User), user_num, file); // 保存用户信息
fclose(file);
printf("航班信息已保存到文件!\n");
}
/*
功能: 从文件读取航班信息
参数: 无
返回值:无
*/
void loadFromFile()
{
FILE *file = fopen("flights.txt", "rb");
if (file == NULL)
{
printf("无法打开文件进行读取,可能是文件不存在!\n");
return;
}
fread(&flight_num, sizeof(int), 1, file); // 先读取航班数量
fread(flights, sizeof(Plane), flight_num, file); // 再读取航班信息
fread(&user_num, sizeof(int), 1, file); // 读取用户数量
fread(users, sizeof(User), user_num, file); // 读取用户信息
fclose(file);
printf("航班信息已从文件加载!\n");
}
/*
功能: 登录功能
参数: 无
返回值:无
*/
void login()
{
char username[20];
char password[20];
printf("请输入用户名: ");
fgets(username, sizeof(username), stdin);
username[strcspn(username, "\n")] = '\0'; // 去除换行符
printf("请输入密码: ");
fgets(password, sizeof(password), stdin);
password[strcspn(password, "\n")] = '\0'; // 去除换行符
for (int i = 0; i < user_num; i++)
{
if (strcmp(users[i].name, username) == 0 && strcmp(users[i].password, password) == 0)
{
printf("登录成功!\n");
Menu(users[i].isAdmin);
return;
}
}
printf("用户名或密码错误,请重试!\n");
exit(1); // 登录失败,退出程序
}
void addUser()
{
if (user_num >= MAX_USERS)
{
printf("无法添加更多用户,已达到最大限制!\n");
return;
}
User newUser;
printf("请输入用户名: ");
fgets(newUser.name, sizeof(newUser.name), stdin);
newUser.name[strcspn(newUser.name, "\n")] = '\0'; // 去除换行符
printf("请输入密码: ");
fgets(newUser.password, sizeof(newUser.password), stdin);
newUser.password[strcspn(newUser.password, "\n")] = '\0'; // 去除换行符
printf("用户类型 (0普通用户/1管理员): ");
scanf("%d", &newUser.isAdmin);
getchar(); // 捕获并丢弃多余的换行符或空格等字符
users[user_num++] = newUser; // 将新用户添加到数组中
printf("用户添加成功!\n");
}
int main()
{
// 初始化一个管理员用户
strcpy(users[user_num].name, "admin");
strcpy(users[user_num].password, "admin123");
users[user_num].isAdmin = 1;
user_num++;
loadFromFile(); // 启动时从文件加载数据
login(); // 登录验证
return 0;
}