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

C语言姓名列表元素处理:排序异常问题求助

问题分析与修复方案

核心问题根源

你的排序异常和错误值输出主要由以下几个关键错误导致:

  • 结构体定义错误:num 被声明为 int num[10];,但实际上每个条目只需要一个编号(单个整数)。数组类型导致存储和读取逻辑完全错误,打印时输出的是数组地址而非实际数值,排序时比较的是指针地址差而非编号大小。
  • 输入处理混乱:sscanf 重复写入 name 字段,同时手动解析字符串的逻辑既冗余又未给字符串添加终止符,引发 strlen、strcmp 等函数的未定义行为。
  • qsort 使用错误:在嵌套循环中多次调用 qsort 完全没必要,只需在所有数据输入完成后调用一次即可。
  • 唯一名字统计逻辑错误:当前逻辑仅当后续没有重复名字时才计数,无法正确统计所有唯一名字的数量。

修复后的完整代码

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

// 修正结构体:num改为单个整数,符合需求
struct people {
    int num;
    char surname[20];
    char name[10];
} peoples[10];

// 修正比较函数:比较单个整数的大小
int compare_people_num(const void *a, const void *b) {
    const struct people *p1 = (const struct people *)a;
    const struct people *p2 = (const struct people *)b;
    return p1->num - p2->num; // 升序排序,反转则返回p2->num - p1->num
}

int main() {
    int i, j, unique_count = 0;
    float avg_surname_len = 0.0f;
    char str[100];
    // 标记名字是否已被统计过
    int name_seen[10] = {0};

    system("chcp 1251 > nul");

    // 输入10组数据,使用sscanf直接解析,避免手动解析的错误
    for (i = 0; i < 10; i++) {
        printf("Enter number, surname, name %d of your human: ", i + 1);
        fgets(str, sizeof(str), stdin);
        // 正确解析编号、姓氏、名字到对应字段
        sscanf(str, "%d %s %s", &peoples[i].num, peoples[i].surname, peoples[i].name);
    }

    // 统计唯一名字数量
    for (i = 0; i < 10; i++) {
        if (!name_seen[i]) {
            unique_count++;
            // 标记所有相同的名字为已统计
            for (j = i + 1; j < 10; j++) {
                if (strcmp(peoples[i].name, peoples[j].name) == 0) {
                    name_seen[j] = 1;
                }
            }
        }
        // 累加姓氏长度
        avg_surname_len += strlen(peoples[i].surname);
    }

    // 仅调用一次qsort完成排序
    qsort(peoples, 10, sizeof(struct people), compare_people_num);

    // 输出排序后的列表
    printf("\nSorted list:\n");
    for (i = 0; i < 10; i++) {
        printf("%d %s %s\n", peoples[i].num, peoples[i].surname, peoples[i].name);
    }

    // 输出统计结果
    printf("\nYou have %d different names\n", unique_count);
    printf("Average length of surname is = %.2f\n", avg_surname_len / 10);

    return 0;
}

关键修复点说明

  1. 结构体修正:将 num 改为单个整数,确保编号的存储和读取正确。
  2. 比较函数修正:直接比较两个 num 的整数值,符合排序逻辑。
  3. 输入逻辑简化:移除冗余的手动字符串解析,使用 sscanf 直接将输入映射到结构体字段,避免错误。
  4. qsort 优化:仅在数据全部输入后调用一次 qsort,提升效率并避免重复排序的问题。
  5. 唯一名字统计修正:使用 name_seen 数组标记已统计的名字,确保每个唯一名字只被计数一次。
  6. 字符串安全:sscanf 读取字符串时会自动添加终止符,避免 strlen 和 strcmp 的未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:15:32