C语言文件记录排序功能失效求助:按人口升序无效果
排查思路与问题修复建议
先从最关键的数据读取环节入手——你的parse_line函数存在明显错误,这直接导致排序(尤其是按population排序)完全失效:
1. parse_line函数的字符串读取错误
在读取area和population字段时,你没有在循环内递增j,导致所有字符都被写入字符串的同一个索引位置,最终只有最后一个字符有效:
- 读取area的循环:
比如如果area是while (line[i] != ' ') { area_str[j] = line[i]; i++; space++; // 这里缺少 j++! }123.45,最终area_str里只会保留最后一个字符5,atof后得到5.0,完全不是原始值。 - 读取population的循环同理:
所有population值都会变成最后一个字符的整数形式(比如原始值是while (line[i] != '\n' && line[i] != '\0') { population_str[j] = line[i]; i++; // 这里也缺少 j++! }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
相关产品推荐
相关产品推荐

