目标:航班查询系统:能够在 Linux 系统 中运行,并用 Makefile 管理项目。
项目文件结构:
flight_system/
├── flight.h # 头文件,声明数据结构与函数
├── flight.c # 实现文件,定义功能函数
├── main.c # 主程序文件,负责菜单交互
├── Makefile # 项目构建文件
功能描述:
信息录入:用户可以输入航班信息,将其存储到链表中。
信息显示:按照起飞时间升序显示航班信息。
信息查询:支持根据关键字(如航班号、起点站、终点站等)进行查询。
删除功能:删除航班功能。
使用 Makefile 管理项目的构建。
方案1(单向链表)
1. 新增功能:修改航班功能设计
用户输入航班号,系统查找对应的航班信息。如果找到该航班,用户可以选择修改以下字段:
1. 起点站
2. 终点站
3. 班期
4. 机型
5. 起飞时间
6. 到达时间
7. 票价
修改后更新链表中的数据。
2. 按票价范围查询功能:
用户输入票价的最低值和最高值,系统遍历链表,查找票价在该范围内的所有航班,并显示结果。如果没有符合条件的航班,提示用户没有找到。
3. 航班信息排序功能:用户可以选择按 起飞时间 或其他字段(如票价)对航班信息进行排序。排序后的结果将更新链表,并按指定顺序显示所有航班信息。
排序方式:
* 按起飞时间排序(升序)
* 按票价排序(升序)
4. 为了防止程序崩溃,需要对用户输入进行更严谨的验证
4.1 常见问题
非法输入:用户输入非预期格式的内容(例如,需要整数时输入了字符串)。
缓冲区溢出:用户输入的数据超出预定义缓冲区长度。
空输入:用户没有输入任何数据。
不符合规则的输入:例如,起飞时间超出 24 小时制范围。
4.2 使用更安全的输入方法
使用 fgets 读取输入,避免缓冲区溢出。
对输入内容进行解析和验证,确保输入符合预期格式。
提供提示,要求用户重新输入合法值。
运行测试
测试非法输入:
1. 输入非整数值(如 abc)时,程序会提示重新输入。
2. 输入超出范围的值(如票价 -100 或起飞时间 2500),程序会提示重新输入。
测试正常功能:
1. 正常输入航班信息,确保数据正确保存。
2. 修改航班信息,确保更新后的值有效且没有崩溃。
5. 支持用户通过多种条件查询航班信息,例如:
根据 起点站 查询。
根据 终点站 查询。
根据 班期 查询。
根据 起飞时间范围 查询。
根据 到达时间范围 查询。
支持组合查询(例如,起点站 + 起飞时间范围)。
方案:
5.1 增加查询条件的函数
为每种查询条件单独实现查询逻辑,例如按起点站查询、按终点站查询、按时间范围查询等。
5.2 添加通用查询函数
使用一个通用查询函数,根据用户选择的条件进行筛选。每个查询条件通过布尔值或特定参数进行判断。
5.3 动态菜单
提供动态查询菜单,允许用户选择单一条件或组合条件查询。
6. 清除输入缓冲区
在每次调用 scanf 读取数字后,立即清除输入缓冲区中的换行符。可以通过以下方法实现:
6.1 在每次调用 scanf 读取整数后,调用 clearInputBuffer。
6.2 改用 fgets 处理所有输入:使用 fgets 替代 scanf,然后通过 sscanf 解析用户输入。fgets 可以更安全地读取整行输入,并防止缓冲区溢出。
方案2(双向链表)
将程序改为使用 双向链表 实现对航班信息的管理,可以更高效地进行删除、插入和遍历操作:
1. 由于代码实现逻辑与单向链表完全一致,文章的篇幅问题,其他功能如排序、查询(按起点站、终点站、时间范围等)和自定义查询可以类似实现,遍历链表时根据条件筛选节点。
双向链表的优点
* 高效删除:可以直接通过前驱指针调整节点,不需要重新遍历链表。
* 灵活插入:可以在任意位置快速插入新节点。
* 易于实现排序:双向链表可以从头或尾进行遍历。
* 可以轻松添加更多功能(如按票价排序、时间范围查询)。
* 支持复杂的自定义查询条件。
方案3(内核链表)
Linux 内核链表 (Kernel Linked List) 实现,可以利用内核链表的高效设计,简化链表操作。
Linux 内核链表通过Linux系统中提供的头文件 <linux/list.h> 提供了强大的链表操作函数,能够减少自己实现链表结构和功能所需的代码。
内核链表本身也是双向循环链表,具备以下优点:
* 通用性强:通过嵌入 struct list_head,可以将链表功能添加到任何结构体。
* 操作简便:提供了宏和函数用于插入、删除、遍历等操作,简化链表管理。
* 性能高:设计高效,避免了许多常见的链表实现问题。
方案一(单向链表实现)
文件:flight.c
#include "flight.h"
// 使用 getchar 循环清空缓冲区
int clearInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF);
return c;
}
// 录入: 将用户输入的航班信息插入到链表中,并保持链表按照 起飞时间升序排列。
void insertFlight(node_list **head) {
// 分配新节点
node_list *newNode = (node_list *)malloc(sizeof(node_list));
if (!newNode) {
printf("内存分配失败!\n");
exit(1);
}
// 输入航班信息
/* printf("请输入航班号: ");
scanf("%s", newNode->info.number);
printf("请输入起点站: ");
scanf("%s", newNode->info.staddress);
printf("请输入终点站: ");
scanf("%s", newNode->info.arraddress);
printf("请输入班期: ");
scanf("%s", newNode->info.DATE);
printf("请输入机型: ");
scanf("%s", newNode->info.TYPE);
printf("请输入起飞时间(24小时制,例如1330): ");
scanf("%d", &newNode->info.stime);
printf("请输入到达时间(24小时制,例如1530): ");
scanf("%d", &newNode->info.atime);
printf("请输入票价: ");
scanf("%d", &newNode->info.value); */
// 输入航班信息
getValidString("请输入航班号: ", newNode->info.number, sizeof(newNode->info.number));
getValidString("请输入起点站: ", newNode->info.staddress, sizeof(newNode->info.staddress));
getValidString("请输入终点站: ", newNode->info.arraddress, sizeof(newNode->info.arraddress));
getValidString("请输入班期: ", newNode->info.DATE, sizeof(newNode->info.DATE));
getValidString("请输入机型: ", newNode->info.TYPE, sizeof(newNode->info.TYPE));
newNode->info.stime = getValidInt("请输入起飞时间(24小时制,例如1330): ", 0, 2359);
newNode->info.atime = getValidInt("请输入到达时间(24小时制,例如1530): ", 0, 2359);
newNode->info.value = getValidInt("请输入票价: ", 0, 100000);
// 插入到链表中,按起飞时间排序
newNode->next = NULL;
if (*head == NULL || (*head)->info.stime > newNode->info.stime) {
// 插入到链表头部
newNode->next = *head;
*head = newNode;
} else {
// 插入到链表中间或尾部
node_list *current = *head;
while (current->next && current->next->info.stime <= newNode->info.stime) {
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
printf("航班信息录入成功!\n");
}
// 显示(按起飞时间排序):遍历链表,按照起飞时间的顺序打印所有航班信息(链表已经按起飞时间排序)。
void displayFlights(node_list *head) {
if (head == NULL) {
printf("没有航班信息!\n");
return;
}
printf("\n航班信息(按起飞时间排序):\n");
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
head = head->next;
}
}
// 查询:支持根据 航班号、起点站 或 终点站 查询航班信息。
void searchFlight(node_list *head) {
if (head == NULL) {
printf("没有航班信息!\n");
return;
}
char keyword[18];
printf("请输入查询关键字(航班号/起点站/终点站): ");
scanf("%s", keyword);
int found = 0;
printf("\n查询结果:\n");
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
if (strcmp(head->info.number, keyword) == 0 ||
strcmp(head->info.staddress, keyword) == 0 ||
strcmp(head->info.arraddress, keyword) == 0) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("没有找到符合条件的航班信息。\n");
}
}
// 删除航班功能
void deleteFlight(node_list **head, const char *flightNumber) {
if (*head == NULL) {
printf("链表为空,没有航班可以删除!\n");
return;
}
node_list *current = *head;
node_list *previous = NULL;
// 遍历链表,寻找匹配的航班号
while (current != NULL) {
if (strcmp(current->info.number, flightNumber) == 0) {
// 找到目标节点
if (previous == NULL) {
// 删除的是头节点
*head = current->next;
} else {
// 删除的是非头节点
previous->next = current->next;
}
printf("航班号 %s 的航班已删除!\n", flightNumber);
free(current); // 释放内存
return;
}
// 继续遍历
previous = current;
current = current->next;
}
printf("未找到航班号为 %s 的航班!\n", flightNumber);
}
// 修改航班信息
void modifyFlight(node_list *head, const char *flightNumber) {
if (head == NULL) {
printf("链表为空,没有航班可以修改!\n");
return;
}
node_list *current = head;
// 遍历链表,找到对应航班号的节点
while (current != NULL) {
if (strcmp(current->info.number, flightNumber) == 0) {
printf("找到航班号为 %s 的航班信息。\n", flightNumber);
// 显示当前信息
printf("\n当前信息:\n");
printf("起点站: %s\n", current->info.staddress);
printf("终点站: %s\n", current->info.arraddress);
printf("班期: %s\n", current->info.DATE);
printf("机型: %s\n", current->info.TYPE);
printf("起飞时间: %04d\n", current->info.stime);
printf("到达时间: %04d\n", current->info.atime);
printf("票价: %d\n", current->info.value);
// 修改信息
/* printf("\n请输入新的信息(若不修改,请输入原值):\n");
printf("起点站: ");
scanf("%s", current->info.staddress);
printf("终点站: ");
scanf("%s", current->info.arraddress);
printf("班期: ");
scanf("%s", current->info.DATE);
printf("机型: ");
scanf("%s", current->info.TYPE);
printf("起飞时间(24小时制,例如1330): ");
scanf("%d", ¤t->info.stime);
printf("到达时间(24小时制,例如1530): ");
scanf("%d", ¤t->info.atime);
printf("票价: ");
scanf("%d", ¤t->info.value); */
printf("\n请输入新的信息(若不修改,请输入原值):\n");
getValidString("起点站: ", current->info.staddress, sizeof(current->info.staddress));
getValidString("终点站: ", current->info.arraddress, sizeof(current->info.arraddress));
getValidString("班期: ", current->info.DATE, sizeof(current->info.DATE));
getValidString("机型: ", current->info.TYPE, sizeof(current->info.TYPE));
current->info.stime = getValidInt("起飞时间(24小时制,例如1330): ", 0, 2359);
current->info.atime = getValidInt("到达时间(24小时制,例如1530): ", 0, 2359);
current->info.value = getValidInt("票价: ", 0, 100000);
printf("航班信息修改成功!\n");
return;
}
current = current->next;
}
printf("未找到航班号为 %s 的航班!\n", flightNumber);
}
// 按票价范围查询航班信息
void searchFlightsByPriceRange(node_list *head, int minPrice, int maxPrice) {
if (head == NULL) {
printf("链表为空,没有航班信息!\n");
return;
}
int found = 0; // 标记是否找到符合条件的航班
printf("\n票价范围 [%d - %d] 的航班信息:\n", minPrice, maxPrice);
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
if (head->info.value >= minPrice && head->info.value <= maxPrice) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("未找到票价范围 [%d - %d] 的航班信息。\n", minPrice, maxPrice);
}
}
// 航班信息排序:使用 冒泡排序 对链表进行排序。
void sortFlights(node_list **head, int mode) {
if (*head == NULL || (*head)->next == NULL) {
printf("链表为空或只有一个航班信息,无需排序!\n");
return;
}
int swapped;
node_list *current;
node_list *last = NULL;
do {
swapped = 0;
current = *head;
while (current->next != last) {
int swapCondition = 0;
// 根据 mode 判断排序方式
if (mode == 1) {
// 按起飞时间排序(升序)
if (current->info.stime > current->next->info.stime) {
swapCondition = 1;
}
} else if (mode == 2) {
// 按票价排序(升序)
if (current->info.value > current->next->info.value) {
swapCondition = 1;
}
}
if (swapCondition) {
// 交换节点数据
datatype temp = current->info;
current->info = current->next->info;
current->next->info = temp;
swapped = 1;
}
current = current->next;
}
last = current;
} while (swapped);
if (mode == 1) {
printf("航班信息已按起飞时间排序(升序)。\n");
} else if (mode == 2) {
printf("航班信息已按票价排序(升序)。\n");
}
}
// 安全输入函数 getValidInt 和 getValidString:
// 获取有效整数(带范围的验证)
int getValidInt(const char *prompt, int min, int max) {
char buffer[32]; // 缓冲区
int value;
while (1) {
printf("%s", prompt);
if (fgets(buffer, sizeof(buffer), stdin)) {
// 尝试解析整数
if (sscanf(buffer, "%d", &value) == 1 && value >= min && value <= max) {
return value;
}
}
printf("无效输入,请输入一个范围在 [%d, %d] 的整数。\n", min, max);
}
}
// 获取有效字符串(长度限制)
void getValidString(const char *prompt, char *dest, size_t maxLen) {
char buffer[128]; // 缓冲区
while (1) {
printf("%s", prompt);
if (fgets(buffer, sizeof(buffer), stdin)) {
size_t len = strlen(buffer);
// 去掉换行符
if (len > 0 && buffer[len - 1] == '\n') {
buffer[len - 1] = '\0';
len--;
}
// 检查长度
if (len > 0 && len < maxLen) {
strncpy(dest, buffer, maxLen);
dest[maxLen - 1] = '\0'; // 确保字符串以 null 结尾
return;
}
}
printf("无效输入,请输入一个长度小于 %zu 的字符串。\n", maxLen);
}
}
// 多种查询条件:
// 查询条件:按起点站查询
void searchFlightsByStart(node_list *head, const char *start) {
if (head == NULL) {
printf("链表为空,没有航班信息!\n");
return;
}
int found = 0;
printf("\n起点站为 '%s' 的航班信息:\n", start);
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
if (strcmp(head->info.staddress, start) == 0) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("未找到起点站为 '%s' 的航班信息。\n", start);
}
}
// 查询条件:按终点站查询
void searchFlightsByDestination(node_list *head, const char *destination) {
if (head == NULL) {
printf("链表为空,没有航班信息!\n");
return;
}
int found = 0;
printf("\n终点站为 '%s' 的航班信息:\n", destination);
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
if (strcmp(head->info.arraddress, destination) == 0) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("未找到终点站为 '%s' 的航班信息。\n", destination);
}
}
// 查询条件:按班期查询
void searchFlightsByDay(node_list *head, const char *day) {
if (head == NULL) {
printf("链表为空,没有航班信息!\n");
return;
}
int found = 0;
printf("\n班期为 '%s' 的航班信息:\n", day);
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
if (strcmp(head->info.DATE, day) == 0) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("未找到班期为 '%s' 的航班信息。\n", day);
}
}
// 查询条件:按时间范围查询
void searchFlightsByTimeRange(node_list *head, int minTime, int maxTime) {
if (head == NULL) {
printf("链表为空,没有航班信息!\n");
return;
}
int found = 0;
printf("\n起飞时间范围 [%04d - %04d] 的航班信息:\n", minTime, maxTime);
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
while (head) {
if (head->info.stime >= minTime && head->info.stime <= maxTime) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("未找到起飞时间范围 [%04d - %04d] 的航班信息。\n", minTime, maxTime);
}
}
// 查询条件:自定义组合查询
void searchFlightsByCustomConditions(node_list *head) {
char start[18] = "";
char destination[18] = "";
int minTime = -1, maxTime = -1;
printf("请输入起点站(留空表示忽略此条件): ");
fgets(start, sizeof(start), stdin);
if (start[strlen(start) - 1] == '\n') start[strlen(start) - 1] = '\0';
printf("请输入终点站(留空表示忽略此条件): ");
fgets(destination, sizeof(destination), stdin);
if (destination[strlen(destination) - 1] == '\n') destination[strlen(destination) - 1] = '\0';
printf("请输入起飞时间范围(例如 0800 1000,输入 0 0 表示忽略此条件): ");
scanf("%d %d", &minTime, &maxTime);
getchar(); // 清除换行符
printf("\n符合条件的航班信息:\n");
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
int found = 0;
while (head) {
int matches = 1;
// 检查起点站
if (strlen(start) > 0 && strcmp(head->info.staddress, start) != 0) {
matches = 0;
}
// 检查终点站
if (strlen(destination) > 0 && strcmp(head->info.arraddress, destination) != 0) {
matches = 0;
}
// 检查起飞时间范围
if (minTime > 0 && maxTime > 0 &&
(head->info.stime < minTime || head->info.stime > maxTime)) {
matches = 0;
}
if (matches) {
found = 1;
printf("%s %s %s %s %s %04d %04d %d\n",
head->info.number, head->info.staddress, head->info.arraddress,
head->info.DATE, head->info.TYPE, head->info.stime,
head->info.atime, head->info.value);
}
head = head->next;
}
if (!found) {
printf("未找到符合条件的航班信息。\n");
}
}
文件:flight.h
#ifndef FLIGHT_H
#define FLIGHT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 航班信息数据结构
typedef struct flight {
char number[18]; // 航班号
char staddress[18]; // 起点站
char arraddress[18]; // 终点站
char DATE[12]; // 班期
char TYPE[8]; // 机型
int stime; // 起飞时间 (24小时制,例如 1330 表示 13:30)
int atime; // 到达时间
int value; // 票价
} datatype;
// 单向链表节点结构
typedef struct Node {
datatype info; // 航班信息
struct Node *next; // 指向下一个节点
} node_list;
// 函数声明
int clearInputBuffer();
void insertFlight(node_list **head); //增
void displayFlights(node_list *head); //遍历链表,查看数据
void searchFlight(node_list *head); //查询数据
void deleteFlight(node_list **head, const char *flightNumber); //删除数据
void modifyFlight(node_list *head, const char *flightNumber); //修改航班信息
void searchFlightsByPriceRange(node_list *head, int minPrice, int maxPrice); //按票价范围查询功能
void sortFlights(node_list **head, int mode); //排序功能 参数1:按起飞时间排序(升序);参数2:按票价排序(升序)
//多种查询条件
void searchFlightsByStart(node_list *head, const char *start);
void searchFlightsByDestination(node_list *head, const char *destination);
void searchFlightsByDay(node_list *head, const char *day);
void searchFlightsByTimeRange(node_list *head, int minTime, int maxTime);
void searchFlightsByCustomConditions(node_list *head);
int getValidInt(const char *prompt, int min, int max);
void getValidString(const char *prompt, char *dest, size_t maxLen);
#endif // FLIGHT_H
主函数:main.c
#include "flight.h"
#include <stdio.h>
int main() {
node_list *head = NULL; // 链表头指针
char input[32]; // 用于读取用户输入
int choice;
while (1) {
printf("\n航班查询系统菜单:\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("9. 按终点站查询\n");
printf("10. 按班期查询\n");
printf("11. 按时间范围查询\n");
printf("12. 自定义组合查询\n");
printf("13. 退出\n");
printf("请输入您的选择: ");
// 使用 fgets 读取用户输入
if (fgets(input, sizeof(input), stdin)) {
// 尝试解析为整数
if (sscanf(input, "%d", &choice) != 1) {
printf("无效输入,请输入数字。\n");
continue; // 回到菜单
}
} else {
printf("输入错误,请重试。\n");
continue; // 回到菜单
}
// 处理用户选择
switch (choice) {
case 1:
insertFlight(&head);
break;
case 2:
displayFlights(head);
break;
case 3:
searchFlight(head);
break;
case 4: {
char flightNumber[18];
getValidString("请输入要删除的航班号: ", flightNumber, sizeof(flightNumber));
deleteFlight(&head, flightNumber);
break;
}
case 5: {
char flightNumber[18];
getValidString("请输入要修改的航班号: ", flightNumber, sizeof(flightNumber));
modifyFlight(head, flightNumber);
break;
}
case 6: {
int minPrice, maxPrice;
printf("请输入票价范围(最低值 最高值): ");
if (fgets(input, sizeof(input), stdin)) {
if (sscanf(input, "%d %d", &minPrice, &maxPrice) == 2) {
searchFlightsByPriceRange(head, minPrice, maxPrice);
} else {
printf("无效输入,请输入两个数字。\n");
}
}
break;
}
case 7: {
int mode;
printf("请选择排序方式:\n");
printf("1. 按起飞时间排序\n");
printf("2. 按票价排序\n");
printf("请输入选择: ");
if (fgets(input, sizeof(input), stdin)) {
if (sscanf(input, "%d", &mode) == 1) {
if (mode == 1 || mode == 2) {
sortFlights(&head, mode);
displayFlights(head);
} else {
printf("无效选择,请输入 1 或 2。\n");
}
} else {
printf("无效输入,请输入数字。\n");
}
}
break;
}
case 8: {
char start[18];
getValidString("请输入起点站: ", start, sizeof(start));
searchFlightsByStart(head, start);
break;
}
case 9: {
char destination[18];
getValidString("请输入终点站: ", destination, sizeof(destination));
searchFlightsByDestination(head, destination);
break;
}
case 10: {
char day[12];
getValidString("请输入班期: ", day, sizeof(day));
searchFlightsByDay(head, day);
break;
}
case 11: {
int minTime, maxTime;
printf("请输入起飞时间范围(最低值 最高值): ");
if (fgets(input, sizeof(input), stdin)) {
if (sscanf(input, "%d %d", &minTime, &maxTime) == 2) {
searchFlightsByTimeRange(head, minTime, maxTime);
} else {
printf("无效输入,请输入两个数字。\n");
}
}
break;
}
case 12:
searchFlightsByCustomConditions(head);
break;
case 13:
printf("退出系统。\n");
return 0;
default:
printf("无效选择,请重新输入!\n");
}
}
return 0;
}
方案二(双向链表实现)
文件:flight_cyc.c
#include "flight_cyc.h"
// 创建一个空的航班链表
FlightList* createFlightList() {
FlightList *list = (FlightList *)malloc(sizeof(FlightList));
if (!list) {
printf("内存分配失败!\n");
exit(1);
}
list->head = NULL;
list->tail = NULL;
return list;
}
// 创建一个新节点
Node* createNode(FlightInfo flight) {
Node *newNode = (Node *)malloc(sizeof(Node));
if (!newNode) {
printf("内存分配失败!\n");
exit(1);
}
newNode->info = flight;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// 插入航班信息:将新航班插入到链表尾部
void insertFlight(FlightList *list) {
FlightInfo flight;
// 输入航班信息
printf("请输入航班号: ");
scanf("%s", flight.number);
printf("请输入起点站: ");
scanf("%s", flight.staddress);
printf("请输入终点站: ");
scanf("%s", flight.arraddress);
printf("请输入班期: ");
scanf("%s", flight.DATE);
printf("请输入机型: ");
scanf("%s", flight.TYPE);
printf("请输入起飞时间(24小时制,例如1330): ");
scanf("%d", &flight.stime);
printf("请输入到达时间(24小时制,例如1530): ");
scanf("%d", &flight.atime);
printf("请输入票价: ");
scanf("%d", &flight.value);
// 创建新节点
Node *newNode = createNode(flight);
// 插入到链表尾部
if (list->tail == NULL) {
list->head = newNode;
list->tail = newNode;
} else {
newNode->prev = list->tail;
list->tail->next = newNode;
list->tail = newNode;
}
printf("航班信息插入成功!\n");
}
// 显示航班信息
void displayFlights(FlightList *list) {
if (list->head == NULL) {
printf("链表为空,没有航班信息!\n");
return;
}
printf("\n航班信息如下:\n");
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
Node *current = list->head;
while (current) {
printf("%s %s %s %s %s %04d %04d %d\n",
current->info.number, current->info.staddress, current->info.arraddress,
current->info.DATE, current->info.TYPE, current->info.stime,
current->info.atime, current->info.value);
current = current->next;
}
}
// 删除航班信息:根据航班号删除对应节点
void deleteFlight(FlightList *list, const char *flightNumber) {
if (list->head == NULL) {
printf("链表为空,没有航班信息可删除!\n");
return;
}
Node *current = list->head;
// 查找目标航班号
while (current) {
if (strcmp(current->info.number, flightNumber) == 0) {
if (current->prev) {
current->prev->next = current->next;
} else {
list->head = current->next;
}
if (current->next) {
current->next->prev = current->prev;
} else {
list->tail = current->prev;
}
free(current);
printf("航班号为 '%s' 的航班信息已删除。\n", flightNumber);
return;
}
current = current->next;
}
printf("未找到航班号为 '%s' 的航班信息。\n", flightNumber);
}
//修改航班信息:根据航班号修改节点数据
void modifyFlight(FlightList *list, const char *flightNumber) {
if (list->head == NULL) {
printf("链表为空,没有航班可以修改!\n");
return;
}
Node *current = list->head;
// 查找目标航班号
while (current) {
if (strcmp(current->info.number, flightNumber) == 0) {
printf("找到航班号为 '%s' 的航班信息。\n", flightNumber);
printf("请输入新的起点站: ");
scanf("%s", current->info.staddress);
printf("请输入新的终点站: ");
scanf("%s", current->info.arraddress);
printf("请输入新的班期: ");
scanf("%s", current->info.DATE);
printf("请输入新的机型: ");
scanf("%s", current->info.TYPE);
printf("请输入新的起飞时间: ");
scanf("%d", ¤t->info.stime);
printf("请输入新的到达时间: ");
scanf("%d", ¤t->info.atime);
printf("请输入新的票价: ");
scanf("%d", ¤t->info.value);
printf("航班信息修改成功!\n");
return;
}
current = current->next;
}
printf("未找到航班号为 '%s' 的航班信息。\n", flightNumber);
}
文件:flight_cyc.h
#ifndef FLIGHT_CYC_H
#define FLIGHT_CYC_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 航班信息数据结构
typedef struct FlightInfo {
char number[18]; // 航班号
char staddress[18]; // 起点站
char arraddress[18]; // 终点站
char DATE[10]; // 班期
char TYPE[12]; // 机型
int stime; // 起飞时间 (24小时制)
int atime; // 到达时间 (24小时制)
int value; // 票价
} FlightInfo;
// 双向链表节点结构
typedef struct Node {
FlightInfo info; // 航班信息
struct Node *prev; // 前驱指针
struct Node *next; // 后继指针
} Node;
// 链表管理结构
typedef struct FlightList {
Node *head; // 链表头指针
Node *tail; // 链表尾指针
} FlightList;
// 函数声明
FlightList* createFlightList();
Node* createNode(FlightInfo flight);
void insertFlight(FlightList *list);
void displayFlights(FlightList *list);
void deleteFlight(FlightList *list, const char *flightNumber);
void modifyFlight(FlightList *list, const char *flightNumber);
void searchFlight(FlightList *list);
void sortFlights(FlightList *list, int mode);
void searchFlightsByStart(FlightList *list, const char *start);
void searchFlightsByDestination(FlightList *list, const char *destination);
void searchFlightsByDay(FlightList *list, const char *day);
void searchFlightsByTimeRange(FlightList *list, int minTime, int maxTime);
void searchFlightsByCustomConditions(FlightList *list);
#endif // FLIGHT_H
文件:main_cyc.c
#include "flight_cyc.h"
int main() {
FlightList *list = createFlightList();
int choice;
while (1) {
printf("\n航班查询系统菜单:\n");
printf("1. 信息录入\n");
printf("2. 信息显示\n");
printf("3. 信息查询\n");
printf("4. 删除航班信息\n");
printf("5. 修改航班信息\n");
printf("6. 退出\n");
printf("请输入您的选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
insertFlight(list);
break;
case 2:
displayFlights(list);
break;
case 3:
searchFlight(list);
break;
case 4: {
char flightNumber[18];
printf("请输入要删除的航班号: ");
scanf("%s", flightNumber);
deleteFlight(list, flightNumber);
break;
}
case 5: {
char flightNumber[18];
printf("请输入要修改的航班号: ");
scanf("%s", flightNumber);
modifyFlight(list, flightNumber);
break;
}
case 6:
printf("退出系统。\n");
return 0;
default:
printf("无效选择,请重新输入!\n");
}
}
return 0;
}
方案三(内核链表实现)
文件:flight_kernel.c
#include "flight.h"
#include "list.h"
// 初始化链表头:LIST_HEAD 是内核链表提供的宏,用于声明和初始化一个链表头。
LIST_HEAD(flightList);
// 插入航班:在链表尾部插入新航班
void insertFlight(struct list_head *head) {
// 创建新航班节点
FlightInfo *newFlight = (FlightInfo *)malloc(sizeof(FlightInfo));
if (!newFlight) {
printf("内存分配失败!\n");
return;
}
// 输入航班信息
printf("请输入航班号: ");
scanf("%s", newFlight->number);
printf("请输入起点站: ");
scanf("%s", newFlight->staddress);
printf("请输入终点站: ");
scanf("%s", newFlight->arraddress);
printf("请输入班期: ");
scanf("%s", newFlight->DATE);
printf("请输入机型: ");
scanf("%s", newFlight->TYPE);
printf("请输入起飞时间(24小时制,例如1330): ");
scanf("%d", &newFlight->stime);
printf("请输入到达时间(24小时制,例如1530): ");
scanf("%d", &newFlight->atime);
printf("请输入票价: ");
scanf("%d", &newFlight->value);
// 添加到链表尾部
list_add_tail(&newFlight->list, head);
printf("航班信息插入成功!\n");
}
// 显示航班:遍历链表并显示所有航班
void displayFlights(struct list_head *head) {
if (list_empty(head)) {
printf("链表为空,没有航班信息!\n");
return;
}
printf("\n航班信息如下:\n");
printf("航班号 起点站 终点站 班期 机型 起飞时间 到达时间 票价\n");
struct list_head *pos;
FlightInfo *flight;
// 遍历链表
list_for_each(pos, head) {
flight = list_entry(pos, FlightInfo, list);
printf("%s %s %s %s %s %04d %04d %d\n",
flight->number, flight->staddress, flight->arraddress,
flight->DATE, flight->TYPE, flight->stime,
flight->atime, flight->value);
}
}
// 删除航班:根据航班号删除航班
void deleteFlight(struct list_head *head, const char *flightNumber) {
if (list_empty(head)) {
printf("链表为空,没有航班信息可删除!\n");
return;
}
struct list_head *pos, *tmp;
FlightInfo *flight;
// 遍历链表并查找目标航班
list_for_each_safe(pos, tmp, head) {
flight = list_entry(pos, FlightInfo, list);
if (strcmp(flight->number, flightNumber) == 0) {
list_del(&flight->list); // 从链表中删除
free(flight); // 释放内存
printf("航班号为 '%s' 的航班信息已删除。\n", flightNumber);
return;
}
}
printf("未找到航班号为 '%s' 的航班信息。\n", flightNumber);
}
// 修改航班:根据航班号修改航班信息
void modifyFlight(struct list_head *head, const char *flightNumber) {
if (list_empty(head)) {
printf("链表为空,没有航班可以修改!\n");
return;
}
struct list_head *pos;
FlightInfo *flight;
// 遍历链表并查找目标航班
list_for_each(pos, head) {
flight = list_entry(pos, FlightInfo, list);
if (strcmp(flight->number, flightNumber) == 0) {
printf("找到航班号为 '%s' 的航班信息。\n", flightNumber);
printf("请输入新的起点站: ");
scanf("%s", flight->staddress);
printf("请输入新的终点站: ");
scanf("%s", flight->arraddress);
printf("请输入新的班期: ");
scanf("%s", flight->DATE);
printf("请输入新的机型: ");
scanf("%s", flight->TYPE);
printf("请输入新的起飞时间: ");
scanf("%d", &flight->stime);
printf("请输入新的到达时间: ");
scanf("%d", &flight->atime);
printf("请输入新的票价: ");
scanf("%d", &flight->value);
printf("航班信息修改成功!\n");
return;
}
}
printf("未找到航班号为 '%s' 的航班信息。\n", flightNumber);
}
文件:flight_kernel.h
#ifndef FLIGHT_H
#define FLIGHT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 内核链表头文件
#include "list.h"
// 航班信息结构体
typedef struct FlightInfo {
char number[18]; // 航班号
char staddress[18]; // 起点站
char arraddress[18]; // 终点站
char DATE[10]; // 班期
char TYPE[12]; // 机型
int stime; // 起飞时间
int atime; // 到达时间
int value; // 票价
struct list_head list; // 内核链表节点
} FlightInfo;
void insertFlight(struct list_head *head);
void displayFlights(struct list_head *head);
void deleteFlight(struct list_head *head, const char *flightNumber);
void modifyFlight(struct list_head *head, const char *flightNumber);
void searchFlight(struct list_head *head);
void sortFlights(struct list_head *head, int mode);
void searchFlightsByStart(struct list_head *head, const char *start);
void searchFlightsByDestination(struct list_head *head, const char *destination);
void searchFlightsByDay(struct list_head *head, const char *day);
void searchFlightsByTimeRange(struct list_head *head, int minTime, int maxTime);
void searchFlightsByCustomConditions(struct list_head *head);
#endif // FLIGHT_H
文件:main_kernel.c
#include "flight.h"
int main() {
int choice;
while (1) {
printf("\n航班查询系统菜单:\n");
printf("1. 信息录入\n");
printf("2. 信息显示\n");
printf("3. 删除航班信息\n");
printf("4. 修改航班信息\n");
printf("5. 退出\n");
printf("请输入您的选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
insertFlight(&flightList);
break;
case 2:
displayFlights(&flightList);
break;
case 3: {
char flightNumber[18];
printf("请输入要删除的航班号: ");
scanf("%s", flightNumber);
deleteFlight(&flightList, flightNumber);
break;
}
case 4: {
char flightNumber[18];
printf("请输入要修改的航班号: ");
scanf("%s", flightNumber);
modifyFlight(&flightList, flightNumber);
break;
}
case 5:
printf("退出系统。\n");
return 0;
default:
printf("无效选择,请重新输入!\n");
}
}
return 0;
}
以上代码经过测试,可以直接复制粘贴即可使用,希望该内容对您有帮助,感谢!
以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。
我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!