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

C语言排序文件三列整数时fscanf读取出错问题排查

问题排查

  • 读取逻辑冗余且容错性差:三次单独调用fscanf读三个整数,未判断行完整性,某行字段缺失时会出现字段错位读取。同时你当前代码读取后仅用count统计有效条数,但后续排序、写入逻辑全用传入的参数n做边界,若实际读取条数count < n,未初始化的数组垃圾值会被写入文件、参与排序,表现为读取到错误数值。
  • 动态内存申请语法错误:你注释掉的malloc写法漏掉了乘法运算符,正确写法为int *array = (int *)malloc(n * 3 * sizeof(int));,语法错误导致你改用栈上变长数组,n较大时会触发栈溢出。
  • 冒泡排序逻辑完全错误:当前循环边界、比较逻辑不符合冒泡排序规则,会出现排序乱序、重复交换的问题,甚至会操作未初始化的数组空间。
  • 无用文件打开操作:你以只读模式打开了index.txt但全程未读取其内容,属于冗余逻辑。
  • 循环提前退出的根因:要么是record.txt中存在非数字字符/字段数量不足,fscanf匹配失败触发break;要么是你传入的参数n远小于实际文件记录数,触发count==n的break条件;如果是首次运行就出错,也有可能是之前测试时异常写入了非法内容到record.txt中,先手动检查文件内容是否为每行三个整数的合法格式。

修复方案

  1. 合并三次fscanf调用为一次,一次性匹配三个整数,返回值不等于3时直接退出循环
  2. 后续排序、写入的边界统一用实际读取到的有效条数count,不要用传入的n
  3. 修正malloc语法,用堆内存存储数组避免栈溢出
  4. 重写冒泡排序逻辑,确保排序规则正确(当前你写的是按学号降序、相同时按课程号降序,若需要升序自行修改比较运算符)
  5. 移除无用的index.txt只读打开逻辑,或者补充对应的读取逻辑

修正后完整代码

void sort_for_bin_search(int n)
{
    FILE *record = fopen("record.txt", "r");
    if (!record)
        return;
    // 改用堆内存存储数组,避免栈溢出
    int *array = (int *)malloc(n * 3 * sizeof(int));
    if (!array) {
        fclose(record);
        return;
    }
    int count = 0;
    int i=0,temp,id,course,score;
    while (count < n)
    {  
        // 一次读取三个整数,容错性更高
        if (fscanf(record, "%d %d %d", &id, &course, &score) != 3) 
            break;
        array[count*3 + 0] = id;
        array[count*3 + 1] = course;
        array[count*3 + 2] = score;
        count++;
    }
    fclose(record);
    // 修正冒泡排序逻辑,边界用实际读取条数count
    for (i = 0; i < count - 1; i++)
    {
        for (int j = 0; j < count - 1 - i; j++)
        {
            int cur_j0 = array[j*3 + 0], cur_j1 = array[j*3 + 1];
            int cur_jn0 = array[(j+1)*3 + 0], cur_jn1 = array[(j+1)*3 + 1];
            int swap_flag = 0;
            if(cur_jn0 > cur_j0) {
                swap_flag = 1;
            } else if(cur_jn0 == cur_j0 && cur_jn1 > cur_j1) {
                swap_flag = 1;
            }
            if(swap_flag) {
                // 交换学号
                temp = array[j*3 + 0];
                array[j*3 + 0] = array[(j+1)*3 + 0];
                array[(j+1)*3 + 0] = temp;
                // 交换课程号
                temp = array[j*3 + 1];
                array[j*3 + 1] = array[(j+1)*3 + 1];
                array[(j+1)*3 + 1] = temp;
                // 交换成绩
                temp = array[j*3 + 2];
                array[j*3 + 2] = array[(j+1)*3 + 2];
                array[(j+1)*3 + 2] = temp;
            }
        }
    }
    FILE *index2 = fopen("index.txt", "w");
    FILE *record2 = fopen("record.txt", "w");
    if(index2 && record2) {
        // 写入边界用实际读取到的count
        for (i = 0; i < count; i++)
        {
            fprintf(index2,"%d\n",array[i*3 + 0]);
            fprintf(record2,"%d %d %d\n",array[i*3 + 0],array[i*3 + 1],array[i*3 + 2]);
        }
        fclose(record2);
        fclose(index2);
    }
    free(array);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 06:24:02