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

C语言座位预订程序:排序时座位信息错乱问题问询

问题分析与解决:座位预订程序排序后座位ID错乱

错误原因

你的代码核心问题在于直接对原始座位数组调用qsort:

  1. qsort会将整个SEAT结构体元素重新排列,包括seatID字段,这直接破坏了原有的座位分配关系——原本绑定的乘客和座位ID被强制拆分重组,完全违背了你“不改变座位分配”的需求。
  2. 数组中未被占用的座位(occupied为0)的seatID大概率是未初始化的垃圾值,排序后这些无效座位会和已占用座位混在一起,即使你通过occupied判断过滤,原数组的顺序已经被打乱,导致显示的座位ID和乘客对应关系彻底错乱。

解决方法

核心思路是:绝不修改原始座位数组,仅对已占用乘客的信息进行排序展示。下面提供两种可行方案:

方案1:使用临时数组存储已占用乘客

先从原数组中提取所有已占用的乘客到临时数组,排序临时数组后输出,原数组完全不受影响:

#include <stdlib.h> // 需要malloc和free的头文件

void alphasortSeat(SEAT seats[], int seatNum) {
    char alphaChoice;
    printf("Sort by first or last name (f or l): ");
    scanf_s(" %c", &alphaChoice, MAXCHOICELEN);

    // 统计已占用座位数量
    int occupiedCount = 0;
    for (int i = 0; i < seatNum; i++) {
        if (seats[i].occupied) {
            occupiedCount++;
        }
    }
    if (occupiedCount == 0) {
        printf("\nNo occupied seats to sort.\n");
        return;
    }

    // 分配临时内存存储已占用乘客
    SEAT* tempSeats = malloc(occupiedCount * sizeof(SEAT));
    if (tempSeats == NULL) {
        fprintf(stderr, "\nERROR: Memory allocation failed.\n");
        return;
    }

    // 填充临时数组
    int idx = 0;
    for (int i = 0; i < seatNum; i++) {
        if (seats[i].occupied) {
            tempSeats[idx++] = seats[i];
        }
    }

    // 排序并输出临时数组
    if (alphaChoice == 'f') {
        qsort(tempSeats, occupiedCount, sizeof(SEAT), firstnameCompare);
        for (int i = 0; i < occupiedCount; i++) {
            printf("\n %s %s is assigned to seat %d.", 
                   tempSeats[i].firstname, tempSeats[i].lastname, tempSeats[i].seatID);
        }
    } else if (alphaChoice == 'l') {
        qsort(tempSeats, occupiedCount, sizeof(SEAT), lastnameCompare);
        for (int i = 0; i < occupiedCount; i++) {
            printf("\n %s %s is assigned to seat %d.", 
                   tempSeats[i].lastname, tempSeats[i].firstname, tempSeats[i].seatID);
        }
    } else {
        fprintf(stderr, "\nERROR: Invalid character entered.\n");
        free(tempSeats);
        return;
    }

    // 释放临时内存,避免内存泄漏
    free(tempSeats);
}

方案2:使用索引数组排序(不复制结构体)

如果不想复制结构体,可以创建一个索引数组,排序索引而非原结构体,通过排序后的索引访问原数组元素:

#include <stdlib.h>

// 针对姓名的索引比较函数(适配qsort_s)
int firstnameIndexCompare(const void* a, const void* b, void* context) {
    const int* idxA = (const int*)a;
    const int* idxB = (const int*)b;
    SEAT* seats = (SEAT*)context;
    return strcmp(seats[*idxA].firstname, seats[*idxB].firstname);
}

int lastnameIndexCompare(const void* a, const void* b, void* context) {
    const int* idxA = (const int*)a;
    const int* idxB = (const int*)b;
    SEAT* seats = (SEAT*)context;
    return strcmp(seats[*idxA].lastname, seats[*idxB].lastname);
}

void alphasortSeat(SEAT seats[], int seatNum) {
    char alphaChoice;
    printf("Sort by first or last name (f or l): ");
    scanf_s(" %c", &alphaChoice, MAXCHOICELEN);

    // 创建索引数组并筛选已占用座位的索引
    int* indices = malloc(seatNum * sizeof(int));
    if (indices == NULL) {
        fprintf(stderr, "\nERROR: Memory allocation failed.\n");
        return;
    }

    int occupiedCount = 0;
    for (int i = 0; i < seatNum; i++) {
        if (seats[i].occupied) {
            indices[occupiedCount++] = i;
        }
    }

    if (occupiedCount == 0) {
        printf("\nNo occupied seats to sort.\n");
        free(indices);
        return;
    }

    // 使用qsort_s排序索引数组,传递原座位数组作为上下文
    if (alphaChoice == 'f') {
        qsort_s(indices, occupiedCount, sizeof(int), firstnameIndexCompare, seats);
        for (int i = 0; i < occupiedCount; i++) {
            int seatIdx = indices[i];
            printf("\n %s %s is assigned to seat %d.", 
                   seats[seatIdx].firstname, seats[seatIdx].lastname, seats[seatIdx].seatID);
        }
    } else if (alphaChoice == 'l') {
        qsort_s(indices, occupiedCount, sizeof(int), lastnameIndexCompare, seats);
        for (int i = 0; i < occupiedCount; i++) {
            int seatIdx = indices[i];
            printf("\n %s %s is assigned to seat %d.", 
                   seats[seatIdx].lastname, seats[seatIdx].firstname, seats[seatIdx].seatID);
        }
    } else {
        fprintf(stderr, "\nERROR: Invalid character entered.\n");
        free(indices);
        return;
    }

    free(indices);
}

注意事项

  • 两种方案都不会修改原始座位数组,保证了座位分配数据的完整性。
  • 记得在使用动态分配的内存后调用free,避免内存泄漏。
  • 方案2使用qsort_s而非qsort,是因为需要传递原座位数组作为比较函数的上下文,如果你坚持使用qsort,可以通过全局变量传递,但不推荐(全局变量会降低代码可维护性)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:17:13