You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言飞机座位预订系统:如何将座位与乘客信息写入txt文件

C语言飞机座位预订程序修复与实现方案

现存代码的直接问题(多数是导致程序崩溃的根源)

  • 数组越界:struct Airplane中seats数组仅定义了6个元素,但初始化、预订逻辑均按10排座位设计,访问超出数组长度的内存会直接触发程序崩溃;struct Seats内的seats数组长度写为10,实际每排仅6个座位(A-F),也存在内存浪费和越界风险
  • 状态不共享:book()函数内部重新定义并初始化了独立的Airplane变量,和main函数中维护的全局座位状态完全隔离,每次调用book都会重置所有座位为空闲,之前的预订记录直接丢失
  • 输入逻辑错误:多处scanf调用漏传地址符&,读取居住城市时错用整数格式符%d,会非法写内存导致程序中途退出;使用fflush(stdin)属于C标准未定义行为,在部分编译器下无法清空输入缓冲区,会导致输入项被残留换行符跳过
  • 文件操作错误:用"w"模式打开存储文件每次都会清空全部历史记录,且打开文件后没有执行任何写入操作,根本无法持久化保存乘客数据
  • 数据无关联:Passenger结构体未存储座位信息,无法把乘客和他订的座位绑定,自然没法实现记录查询、改签、删除功能

必要的结构体修改

先修正结构体定义,补充座位关联字段,固定数组长度避免越界:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_ROWS 10    // 总排数10
#define MAX_COLS 6     // 每排6座 A-F
#define MAX_STR_LEN 50 // 姓名、城市最大长度
#define DATA_FILE "Passengers.txt"

struct Passenger{
    int pnum;
    int age;
    char city[MAX_STR_LEN];
    char name[MAX_STR_LEN];
    int seat_row;  // 新增:绑定座位排号 1~10
    char seat_col; // 新增:绑定座位列号 A~F
};

struct Seats{
    int row;
    char seats[MAX_COLS]; // 修正长度为每排6座
};

struct Airplane{
    struct Seats seats[MAX_ROWS]; // 修正长度为总排数10
    int booked_count; // 全局统计已预订座位数,不用每次遍历计算
};

修正初始化函数,匹配数组长度,程序启动时先加载历史文件恢复座位状态:

// 清空输入缓冲区的工具函数,替代未定义的fflush(stdin)
void clear_input_buffer() {
    int c;
    while((c = getchar()) != '\n' && c != EOF);
}

void initializeDefault(struct Airplane *airplane){
    airplane->booked_count = 0;
    for(int i=0;i<MAX_ROWS;i++){
        airplane->seats[i].row = i+1;
        for(int j=0;j<MAX_COLS;j++){
            airplane->seats[i].seats[j] = 'A' + j; // 空闲座位存原字符,预订后改为'X'
        }
    }

    // 启动时加载历史预订记录,恢复座位状态
    FILE *fp = fopen(DATA_FILE, "r");
    if(fp == NULL) return; // 第一次运行无文件直接返回
    struct Passenger tmp;
    while(fscanf(fp, "%d %49s %d %49s %d %c", 
        &tmp.pnum, tmp.name, &tmp.age, tmp.city, &tmp.seat_row, &tmp.seat_col) == 6) {
        int r = tmp.seat_row - 1;
        int c = toupper(tmp.seat_col) - 'A';
        if(r >=0 && r < MAX_ROWS && c >=0 && c < MAX_COLS && airplane->seats[r].seats[c] != 'X') {
            airplane->seats[r].seats[c] = 'X';
            airplane->booked_count++;
        }
    }
    fclose(fp);
}

book()函数实现逻辑

所有座位操作函数都要传入main中维护的Airplane指针,保证全局状态一致;预订成功后同步把乘客+绑定的座位信息写入文件:

// 注意传入Airplane指针,共享全局座位状态
void book(struct Airplane *airplane){
    if(airplane->booked_count == MAX_ROWS * MAX_COLS) {
        printf("\nAll seats are booked now.\n");
        return;
    }

    int n, i;
    printf("How many passengers/seats you want to reserve?: ");
    scanf("%d", &n);
    clear_input_buffer();

    struct Passenger *p = (struct Passenger*)malloc(n * sizeof(struct Passenger));
    // 追加模式打开文件,新预订记录追加到末尾,不会清空历史
    FILE *fp = fopen(DATA_FILE, "a");
    if(fp == NULL) {
        printf("Failed to open data file.\n");
        free(p);
        return;
    }

    for(i=0;i<n;i++){
        if(airplane->booked_count >= MAX_ROWS * MAX_COLS) {
            printf("No enough available seats, stop booking.\n");
            break;
        }
        printf("Enter passenger ID: ");
        scanf("%d", &p[i].pnum); // 注意加&传地址
        clear_input_buffer();

        printf("Enter #%d passenger's name: ", i+1);
        scanf("%49[^\n]", p[i].name); // 限制长度避免缓冲区溢出
        clear_input_buffer();

        printf("What's the passenger's age?: ");
        scanf("%d", &p[i].age);
        clear_input_buffer();

        printf("Please enter the city where the passenger resides: ");
        scanf("%49[^\n]", p[i].city);
        clear_input_buffer();

        int row, valid = 0;
        char col;
        do {
            printf("\nEnter Seat row (1-10): ");
            scanf("%d", &row);
            clear_input_buffer();
            printf("Enter Seat column (A-F): ");
            scanf("%c", &col);
            col = toupper(col); // 自动转大写,支持用户输入小写a-f
            clear_input_buffer();

            if(row <1 || row > MAX_ROWS || col <'A' || col > 'F') {
                printf("Invalid seat number, please re-enter.\n");
                continue;
            }
            if(airplane->seats[row-1].seats[col-'A'] == 'X') {
                printf("Seat %d%c is already booked, please choose another.\n", row, col);
                continue;
            }
            valid = 1;
        } while(!valid);

        // 标记座位为已预订
        airplane->seats[row-1].seats[col-'A'] = 'X';
        airplane->booked_count++;
        // 把座位信息绑定到乘客结构体
        p[i].seat_row = row;
        p[i].seat_col = col;
        // 同步写入文件
        fprintf(fp, "%d %s %d %s %d %c\n", 
            p[i].pnum, p[i].name, p[i].age, p[i].city, p[i].seat_row, p[i].seat_col);
        printf("Seat %d%c is booked successfully.\n\n", row, col);
    }

    fclose(fp);
    free(p);
}

其余功能实现提示

  • 座位展示(功能2):直接遍历Airplane的seats数组,每排遍历6个座位,如果字符是'X'就显示X,否则显示原座位字符(A-F)即可
  • 预订记录展示(功能5):逐行读取Passengers.txt,按写入时的格式解析出Passenger结构体的所有字段,格式化输出姓名、年龄、城市、座位号即可
  • 改签、删除功能:操作时先更新Airplane中对应座位的状态,再把文件中所有有效记录重新写入(删除旧记录、写入更新后的记录),保证文件和内存状态一致
  • main函数中调用book时,需要传入airplane的地址:case 1: book(&airplane); break;,其余功能函数如果要操作座位状态,也需要传入这个指针

内容的提问来源于stack exchange,提问作者Valentine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:27:04