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

C语言读取dist.txt按NDist排序输出异常应如何排查修复?

问题根因排查

你的代码存在4处核心错误,直接导致字段错位、空数据异常:

  • 未初始化f变量就判断while(f != EOF),且f定义为char类型无法正确存储EOF值(EOF是int类型的-1,char为无符号时会截断为255,永远不等于EOF)
  • 读取文件的循环逻辑完全错误:你没有判断fscanf的返回值,哪怕文件读取失败、已经到末尾,仍会执行v++,大量未初始化的结构体垃圾值被纳入排序和输出流程
  • fgetc的多余操作破坏了读取指针位置:fscanf读完一行后已经自动跳过空白符(包括换行),你额外读一个字符会吞掉下一行的第一个字符,直接导致后续字段错位
  • 读取字符串时没有做长度限制,SCode只有5字节长度,一旦输入的编码超过4个字符就会发生缓冲区溢出,破坏内存数据

修正后代码

struct sortD
{
    char supply[50], SCode[8], Cdonator[50]; // 给SCode多留冗余空间避免溢出
    int IDd;
    double NDist;
}mp[300];

void sortD()
{
    struct sortD rmp;
    int v=0, size1, q;
    int read_ret; // 存储fscanf返回值判断读取结果
    FILE * fpp = fopen("dist.txt", "r");
    if (fpp == NULL)
    {
        printf ("\nCan not open file.\n");
        return;
    }

    // 修正循环逻辑:用fscanf返回值判断读取是否成功,同时限制数组最大长度避免越界
    while (v < 300) {
        read_ret = fscanf(fpp, "%d %49s %7s %49s %lf", 
                    &mp[v].IDd, mp[v].supply, mp[v].SCode, mp[v].Cdonator, &mp[v].NDist);
        if (read_ret != 5) break; // 没有读满5个字段说明读取失败/到达文件末尾,退出循环
        v++;
    }
    fclose(fpp); // 读取完成后关闭文件释放资源

    size1 = v;
    // 冒泡排序逻辑微调适配实际读取到的元素数量
    for (v=0;v<size1-1;++v){
        for (q=0;q<size1 - 1 - v;q++){
            if (mp[q+1].NDist > mp[q].NDist)
            {
                rmp=mp[q];
                mp[q]=mp[q+1];
                mp[q+1]=rmp;
            }
        }
    }

    for (v=0;v<size1;v++){
        printf ("ID: %d Name of Supply: %s, Supply Code: %s, Donator: %s, Number Donated (Million): %lf\n", 
            mp[v].IDd, mp[v].supply, mp[v].SCode,mp[v].Cdonator, mp[v].NDist);
    }
}

补充说明

如果你的dist.txt里的物资名称、捐赠方名称包含空格,那%s格式符无法正确读取(遇到空格就截断),需要换成%[^\t]或者按行读取后拆分字段,你可以根据实际文件的分隔规则调整读取逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:27:03