二进制文件数组位置打印代码无限循环问题排查
问题分析与修复方案
你的代码出现无限循环的核心原因是错误使用feof(f)作为循环判断条件:
feof()不会提前告知文件即将到达末尾,它只有在尝试读取操作(比如fread)失败后,才会标记文件结束状态。- 当文件指针已经走到末尾时,循环依然会进入一次:此时
printf会打印当前末尾位置,fread读取n失败(返回0),但n是未初始化的局部变量,值为随机值,执行fseek时会根据这个随机值移动指针,导致指针永远无法停在正确的末尾位置,最终陷入无限循环。
修复后的代码
#include <stdio.h> int main() { FILE *f = fopen("a.bin", "rb"); if (!f) { // 检查文件是否成功打开 perror("fopen failed"); return 1; } long n; // 以fread的返回值作为循环判断条件,确保成功读取到数组长度n才继续 while (fread(&n, sizeof(long), 1, f) == 1) { // 计算并打印数组起始位置:读取n后指针已偏移sizeof(long),所以要回退 printf("-(%ld)\n", ftell(f) - sizeof(long)); // 跳过当前数组的n个long类型元素 if (fseek(f, n * sizeof(long), SEEK_CUR) != 0) { perror("fseek failed"); break; } } fclose(f); // 记得关闭文件释放资源 return 0; }
关键改动说明
- 循环逻辑重构:把
fread的返回值作为循环条件,成功读取到n(返回1)才进入循环,读取失败或到末尾直接退出,从根源避免无效循环。 - 修正格式化符:
ftell返回long类型,原代码用%d会导致类型不匹配,改为%ld保证输出正确。 - 起始位置修正:读取
n后指针已经移动了sizeof(long),所以数组起始位置是当前指针位置减去该长度。 - 增加错误检查:补充文件打开失败、指针移动失败的判断,避免程序崩溃或异常行为。
- 资源释放:添加
fclose确保文件资源正常释放。
内容的提问来源于stack exchange,提问作者IuLius
相关产品推荐
相关产品推荐

