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

C语言文件记录排序功能失效求助:按人口升序无效果

排查思路与问题修复建议

先从最关键的数据读取环节入手——你的parse_line函数存在明显错误,这直接导致排序(尤其是按population排序)完全失效:

1. parse_line函数的字符串读取错误

在读取area和population字段时,你没有在循环内递增j,导致所有字符都被写入字符串的同一个索引位置,最终只有最后一个字符有效:

  • 读取area的循环:
    while (line[i] != ' ') {
      area_str[j] = line[i];
      i++;
      space++;
      // 这里缺少 j++!
    }
    
    比如如果area是123.45,最终area_str里只会保留最后一个字符5,atof后得到5.0,完全不是原始值。
  • 读取population的循环同理:
    while (line[i] != '\n' && line[i] != '\0') {
      population_str[j] = line[i];
      i++;
      // 这里也缺少 j++!
    }
    
    所有population值都会变成最后一个字符的整数形式(比如原始值是10000,最后得到0),所以按population排序时,所有元素的值都相同,自然看不出任何变化。

修复方法:在两个循环内添加j++,确保每个字符写入字符串的对应位置:

// 读取area的循环修改后
while (line[i] != ' ') {
  area_str[j] = line[i];
  i++;
  j++; // 新增这行
}

// 读取population的循环修改后
while (line[i] != '\n' && line[i] != '\0') {
  population_str[j] = line[i];
  i++;
  j++; // 新增这行
}

2. 排序与写入的循环边界错误

你的x变量是数组最后一个元素的索引(初始值-1,每读一行x++),所以数组的总元素数是x+1个,但你的循环边界都少处理了一个元素:

  • 排序时的外层循环:for(int i = 0; i < x - 1; i++)
    这个条件会让外层循环少执行一轮,导致最后两个元素没有参与比较排序,部分元素的顺序不会被修正。
    应该改为:for(int i = 0; i < x; i++)(因为x+1个元素需要x轮外层循环)
  • 写入文件的循环:for (int i = 0; i < x; i++)
    这个条件会漏掉最后一个元素ar[x],导致写入的内容比读取的少一行,覆盖原文件后内容不完整。
    应该改为:for (int i = 0; i <= x; i++)(或者i < x+1)

3. 文件操作的潜在问题

  • 你打开临时文件f的逻辑嵌套在ftemp打开成功的if块里,但后续的写入和关闭操作却在块外。如果fopen(temp, "w")失败,f会是NULL,此时fprintf和fclose(f)都会触发未定义行为,甚至程序崩溃。
    建议把排序和写入的代码都放到f打开成功的if块内,避免空指针操作。
  • fflush(stdin)是C标准未定义的行为,不同编译器处理方式不同,建议用以下代码清除输入缓冲区:
    while(getchar() != '\n'); // 代替fflush(stdin)
    

4. 调试建议

在排查这类问题时,可以添加一些调试输出:

  • 在parse_line函数返回前,打印解析后的record内容,确认数据是否正确读取;
  • 排序完成后,打印数组中所有元素的region、area、population值,确认排序逻辑是否生效;
  • 检查临时文件temp的内容,确认写入是否成功,再看rename操作是否正确执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:15:37