飞机订票系统 C语言课程设计
项目概述与需求分析
1 项目目标
设计并实现一个基于C语言的飞机订票系统,该系统应能够模拟航空公司的订票、退票、航班信息查询等核心业务流程,通过本设计,旨在加深对C语言中结构体、文件操作、指针、函数模块化设计等核心知识的理解和应用。

(图片来源网络,侵删)
2 功能需求分析
系统需要具备以下基本功能:
- 航班信息录入:管理员可以手动添加新的航班信息,包括航班号、起点站、终点站、日期、时间、总座位数、已订票数等。
- 航班信息浏览:以清晰、有序的表格形式显示所有航班的详细信息。
- 航班信息查询:用户可以根据航班号或终点站来查询特定的航班信息。
- 订票功能:
- 用户选择一个航班后,可以输入订票数量。
- 系统自动判断该航班的剩余票数是否足够。
- 如果足够,则更新该航班的已订票数,并提示订票成功,显示订单信息。
- 如果票数不足,则提示用户票数已满或不足。
- 退票功能:
- 用户输入要退票的航班号和退票数量。
- 系统验证该航班的已订票数是否足够退票。
- 如果足够,则更新该航班的已订票数,并提示退票成功。
- 如果不足,则提示退票失败。
- 数据持久化:所有航班信息应保存在文件中(如
flights.dat),程序启动时自动从文件加载数据,退出时自动保存数据,确保数据不丢失。 - 用户界面:提供清晰的菜单界面,引导用户选择所需功能。
系统设计
1 数据结构设计
为了存储航班信息,我们使用结构体 Flight。
// 航班信息结构体
typedef struct {
char flight_number[20]; // 航班号, e.g., "CA1234"
char origin[20]; // 起点站
char destination[20]; // 终点站
char date[20]; // 日期, e.g., "2025-12-25"
char time[20]; // 时间, e.g., "08:00"
int total_seats; // 总座位数
int booked_seats; // 已订票数
} Flight;
2 功能模块设计
系统将采用模块化设计思想,将不同功能封装在独立的函数中,提高代码的可读性和可维护性。
| 模块名称 | 函数名 | 功能描述 |
|---|---|---|
| 主菜单 | main() |
程序入口,显示主菜单,调用其他功能函数 |
| 文件操作 | loadFlights() |
从 flights.dat 文件加载航班数据到内存 |
saveFlights() |
将内存中的航班数据保存到 flights.dat 文件 |
|
| 航班管理 | addFlight() |
添加一个新航班 |
displayFlights() |
显示所有航班信息 | |
searchFlight() |
根据航班号或终点站查询航班 | |
| 订票/退票 | bookTicket() |
处理订票逻辑 |
cancelTicket() |
处理退票逻辑 | |
| 辅助功能 | getFlightByNumber() |
通过航班号查找航班指针(供订票/退票使用) |
clearScreen() |
清屏函数,优化界面显示 |
核心代码实现
以下是完整的C语言代码,包含了上述所有功能模块。

(图片来源网络,侵删)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h> // 用于 getch(),实现无回显输入
#define MAX_FLIGHTS 100
#define FILENAME "flights.dat"
// 航班信息结构体
typedef struct {
char flight_number[20];
char origin[20];
char destination[20];
char date[20];
char time[20];
int total_seats;
int booked_seats;
} Flight;
Flight flights[MAX_FLIGHTS]; // 航班数组
int flight_count = 0; // 当前航班数量
// 函数声明
void loadFlights();
void saveFlights();
void addFlight();
void displayFlights();
void searchFlight();
void bookTicket();
void cancelTicket();
Flight* getFlightByNumber(const char* number);
void clearScreen();
void showMenu();
int main() {
loadFlights(); // 程序启动时加载数据
int choice;
do {
showMenu();
printf("请输入您的选择: ");
scanf("%d", &choice);
while (getchar() != '\n'); // 清除输入缓冲区
switch (choice) {
case 1:
addFlight();
break;
case 2:
displayFlights();
break;
case 3:
searchFlight();
break;
case 4:
bookTicket();
break;
case 5:
cancelTicket();
break;
case 0:
printf("感谢使用,再见!\n");
break;
default:
printf("无效的选择,请重新输入!\n");
break;
}
if (choice != 0) {
printf("\n按任意键返回主菜单...");
getch();
}
} while (choice != 0);
saveFlights(); // 程序退出时保存数据
return 0;
}
// 显示主菜单
void showMenu() {
clearScreen();
printf("========================================\n");
printf(" 欢迎使用飞机订票系统\n");
printf("========================================\n");
printf(" 1. 录入航班信息\n");
printf(" 2. 浏览航班信息\n");
printf(" 3. 查询航班信息\n");
printf(" 4. 订票\n");
printf(" 5. 退票\n");
printf(" 0. 退出系统\n");
printf("========================================\n");
}
// 从文件加载航班数据
void loadFlights() {
FILE *file = fopen(FILENAME, "rb");
if (file == NULL) {
// 文件不存在,首次运行
return;
}
fread(&flight_count, sizeof(int), 1, file);
fread(flights, sizeof(Flight), flight_count, file);
fclose(file);
}
// 保存航班数据到文件
void saveFlights() {
FILE *file = fopen(FILENAME, "wb");
if (file == NULL) {
printf("错误:无法保存数据到文件!\n");
return;
}
fwrite(&flight_count, sizeof(int), 1, file);
fwrite(flights, sizeof(Flight), flight_count, file);
fclose(file);
}
// 添加航班
void addFlight() {
if (flight_count >= MAX_FLIGHTS) {
printf("航班数量已达上限,无法添加!\n");
return;
}
Flight new_flight;
printf("请输入航班号: ");
scanf("%s", new_flight.flight_number);
printf("请输入起点站: ");
scanf("%s", new_flight.origin);
printf("请输入终点站: ");
scanf("%s", new_flight.destination);
printf("请输入日期 (YYYY-MM-DD): ");
scanf("%s", new_flight.date);
printf("请输入时间 (HH:MM): ");
scanf("%s", new_flight.time);
printf("请输入总座位数: ");
scanf("%d", &new_flight.total_seats);
new_flight.booked_seats = 0;
flights[flight_count++] = new_flight;
printf("航班信息添加成功!\n");
}
// 显示所有航班
void displayFlights() {
if (flight_count == 0) {
printf("当前没有航班信息!\n");
return;
}
clearScreen();
printf("------------------------------------------------------------\n");
printf(" 航班号 起点站 终点站 日期 时间 总座位 已订票\n");
printf("------------------------------------------------------------\n");
for (int i = 0; i < flight_count; i++) {
printf(" %-6s %-6s %-8s %-10s %-5s %-6d %-6d\n",
flights[i].flight_number,
flights[i].origin,
flights[i].destination,
flights[i].date,
flights[i].time,
flights[i].total_seats,
flights[i].booked_seats);
}
printf("------------------------------------------------------------\n");
}
// 查询航班
void searchFlight() {
if (flight_count == 0) {
printf("当前没有航班信息!\n");
return;
}
int option;
char keyword[20];
printf("请选择查询方式:\n");
printf(" 1. 按航班号查询\n");
printf(" 2. 按终点站查询\n");
printf("请输入选择: ");
scanf("%d", &option);
printf("请输入查询关键词: ");
scanf("%s", keyword);
int found = 0;
clearScreen();
printf("------------------------------------------------------------\n");
printf(" 航班号 起点站 终点站 日期 时间 总座位 已订票\n");
printf("------------------------------------------------------------\n");
for (int i = 0; i < flight_count; i++) {
if ((option == 1 && strcmp(flights[i].flight_number, keyword) == 0) ||
(option == 2 && strcmp(flights[i].destination, keyword) == 0)) {
printf(" %-6s %-6s %-8s %-10s %-5s %-6d %-6d\n",
flights[i].flight_number,
flights[i].origin,
flights[i].destination,
flights[i].date,
flights[i].time,
flights[i].total_seats,
flights[i].booked_seats);
found = 1;
}
}
if (!found) {
printf("未找到匹配的航班!\n");
}
printf("------------------------------------------------------------\n");
}
// 订票
void bookTicket() {
if (flight_count == 0) {
printf("当前没有航班信息!\n");
return;
}
displayFlights();
char number[20];
int quantity;
printf("\n请输入要预订的航班号: ");
scanf("%s", number);
Flight *flight = getFlightByNumber(number);
if (flight == NULL) {
printf("未找到该航班!\n");
return;
}
printf("请输入预订票数: ");
scanf("%d", &quantity);
if (quantity <= 0) {
printf("订票数量必须大于0!\n");
return;
}
if (flight->booked_seats + quantity > flight->total_seats) {
printf("订票失败!剩余票数不足,\n");
printf("当前剩余票数: %d\n", flight->total_seats - flight->booked_seats);
} else {
flight->booked_seats += quantity;
printf("订票成功!\n");
printf("航班: %s, %s -> %s\n", flight->flight_number, flight->origin, flight->destination);
printf("已成功预订 %d 张票,\n", quantity);
}
}
// 退票
void cancelTicket() {
if (flight_count == 0) {
printf("当前没有航班信息!\n");
return;
}
char number[20];
int quantity;
printf("请输入要退票的航班号: ");
scanf("%s", number);
Flight *flight = getFlightByNumber(number);
if (flight == NULL) {
printf("未找到该航班!\n");
return;
}
printf("请输入退票数量: ");
scanf("%d", &quantity);
if (quantity <= 0) {
printf("退票数量必须大于0!\n");
return;
}
if (flight->booked_seats < quantity) {
printf("退票失败!已订票数不足,\n");
printf("当前已订票数: %d\n", flight->booked_seats);
} else {
flight->booked_seats -= quantity;
printf("退票成功!\n");
printf("航班: %s, %s -> %s\n", flight->flight_number, flight->origin, flight->destination);
printf("已成功退票 %d 张,\n", quantity);
}
}
// 通过航班号获取航班指针
Flight* getFlightByNumber(const char* number) {
for (int i = 0; i < flight_count; i++) {
if (strcmp(flights[i].flight_number, number) == 0) {
return &flights[i];
}
}
return NULL; // 未找到
}
// 清屏函数 (Windows)
void clearScreen() {
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
系统测试与演示
1 环境配置
- 编译器:GCC (MinGW on Windows), Clang, 或 Visual Studio C++。
- IDE:VS Code, Dev-C++, Visual Studio 等。
- 注意事项:代码中使用了
conio.h库中的getch()函数,这在Windows环境下很常见,如果你在Linux或Mac上编译,需要移除#include <conio.h>和getch()调用,并用printf("..."); getchar();替代。
2 测试步骤演示
-
首次运行:
- 编译并运行程序。
flights.dat文件不存在。 - 选择
录入航班信息,添加几条模拟数据。- 航班号:
MU5101, 起点站:北京, 终点站:上海, 日期:2025-12-30, 时间:09:00, 总座位:150。 - 航班号:
CZ3210, 起点站:广州, 终点站:成都, 日期:2025-12-30, 时间:14:30, 总座位:120。
- 航班号:
- 退出程序,此时会发现同目录下生成了
flights.dat文件。
- 编译并运行程序。
-
再次运行(数据持久化测试):
- 再次运行程序,航班信息应该还在。
- 选择
浏览航班信息,检查之前添加的航班是否正确显示。
-
查询功能测试:
- 选择
查询航班信息。 - 选择
按航班号查询,输入MU5101,应能查到对应航班。 - 选择
按终点站查询,输入上海,应能查到MU5101。
- 选择
-
订票功能测试:
(图片来源网络,侵删)- 选择
订票。 - 输入航班号
MU5101,订票数量10,提示订票成功,并显示剩余票数为140。 - 再次浏览航班信息,确认
MU5101的已订票数已更新为10。 - 再次尝试订票
MU5101,数量141,系统应提示“票数不足”。
- 选择
-
退票功能测试:
- 选择
退票。 - 输入航班号
MU5101,退票数量5,提示退票成功,并显示剩余票数为145。 - 测试退票数量大于已订票数的情况,系统应提示“已订票数不足”。
- 选择
总结与展望
1 总结
本飞机订票系统实现了课程设计要求的所有核心功能,包括航班信息的增删改查、订票退票以及数据持久化,系统采用了模块化的设计思想,代码结构清晰,易于理解和扩展,通过本次设计,巩固了C语言的核心知识点,特别是结构体、文件I/O和函数指针的应用。
2 不足与展望
此系统仍有可以改进和扩展的地方:
- 用户管理:可以增加用户登录模块,区分管理员和普通用户,拥有不同的操作权限。
- 订单管理:可以为每次订票生成一个唯一的订单号,并存储订单信息(如乘客姓名、身份证号),实现更完整的订票流程。
- 数据结构优化:当前使用静态数组,如果航班数量巨大,会造成内存浪费,可以改用动态链表或文件直接索引来管理数据。
- 界面美化:可以使用
ncurses库(Linux)或 Windows API 来创建更美观的图形用户界面。 - 输入验证:可以增加更严格的输入验证,例如检查日期格式、时间格式、票数是否为正整数等,增强程序的健壮性。
这个项目为你提供了一个坚实的基础,你可以在此基础上进行二次开发,打造一个功能更加强大的订票系统,祝你课程设计顺利!
