使用feof和fseek统计二进制文件条目数量时循环无法终止的修复咨询
修复使用feof和fseek统计二进制文件条目数量的循环终止问题
问题描述
需要统计二进制文件中的条目数量,文件每条条目格式为:int类型的名称长度 + char类型的名称 + float类型的薪资。原代码使用feof和fseek实现,但循环无法终止,代码如下:
int count_items(FILE* file) { int count=0; int curr_name_len; while (!feof(file)) { fread(&curr_name_len, sizeof(int), 1, file); fseek(file, (curr_name_len * sizeof(char)) + sizeof(float), SEEK_CUR); count++; } rewind(file); return count; }
问题原因
- feof的判断逻辑错误:
feof()仅在程序尝试读取超出文件末尾时才会返回真,因此while(!feof(file))会让代码在文件实际到达末尾后,仍执行一次循环体。 - 未校验fread的读取结果:当
fread因到达文件末尾读取失败时,curr_name_len会是未初始化的垃圾值,用这个值执行fseek会导致文件指针跳转到错误位置,甚至陷入无限循环。
修复方案
通过检查fread的返回值控制循环,确保只有成功读取到名称长度时,才继续处理条目并计数:
int count_items(FILE* file) { int count = 0; int curr_name_len; // 成功读取一个int类型的名称长度时,进入循环 while (fread(&curr_name_len, sizeof(int), 1, file) == 1) { // 跳过名称和薪资部分 fseek(file, curr_name_len + sizeof(float), SEEK_CUR); count++; } rewind(file); return count; }
关键改动说明
- 用
fread的返回值作为循环条件:fread返回成功读取的元素个数,返回1表示成功读取名称长度,继续处理;返回0表示到达文件末尾或读取失败,终止循环。 - 避免了
feof的逻辑陷阱,同时确保只有读取有效数据后才执行后续的fseek和计数操作,不会因垃圾值导致指针跳转错误。
内容的提问来源于stack exchange,提问作者Pentakorr
相关产品推荐
相关产品推荐

