fseek()使用不当致二进制文件员工薪资更新循环无法终止?
解决二进制文件更新员工薪资时循环无法终止的问题
我明白你遇到的困扰了——在更新二进制文件里的员工薪资时,明明只有2名员工,循环却一直停不下来,核心问题出在文件指针的处理和循环条件的判断上。咱们一步步拆解:
原代码的问题分析
先看你最初的实现:
void updateSalary(char* filename) { int i = 0; employee temp; char c; float increase; FILE *fup = fopen(filename, "rb+"); if (fup == NULL) { printf("Unable to read the file\n"); return; } fread(&temp, sizeof(employee), 1, fup); while (!feof(fup)) { printf("How big is the increase to %s's salary?\n", temp.name); scanf("%f", &increase); temp.salary += increase; fseek(fup, (i * sizeof(employee)), SEEK_SET); fwrite(&temp, sizeof(employee), 1, fup); fread(&temp, sizeof(employee), 1, fup); i++; } fclose(fup); }
这里有两个关键问题:
while (!feof(fup))的逻辑陷阱:feof()只有在你尝试读取超出文件末尾之后,才会被置为真。这意味着当你读完最后一条记录后,还会再进入一次循环,触发不必要的操作,甚至导致循环无法正常终止。- 文件指针定位错误:写完当前记录后,
fwrite确实会移动文件指针,但原代码没有确保写完后指针指向了下一条记录的起始位置,加上feof的问题,直接导致循环停不下来。
修正后的代码及解释
你调整后的代码已经解决了核心问题,我再帮你梳理下关键修正点:
void updateSalary(char* filename, float threshold) { int i = 0; employee temp; char c; float increase; FILE *fup = fopen(filename, "r+b"); if (fup == NULL) { printf("Unable to read the file\n"); return; } //fread(&temp, sizeof(employee), 1, fup); while (fread(&temp, sizeof(employee), 1, fup)) { printf("How big is the increase to %s's salary?\n", temp.name); rewind(stdin); scanf("%f", &increase); temp.salary += increase; fseek(fup, (i * sizeof(employee)), SEEK_SET); fwrite(&temp, sizeof(employee), 1, fup); fseek(fup, ((i+1) * sizeof(employee)), SEEK_SET); // 关键修正 i++; } fclose(fup); }
核心改进点:
- 循环条件改为
while (fread(...)):直接用fread的返回值判断是否成功读取到记录,只要读取失败(到文件末尾)就立即退出循环,完美避开了feof的陷阱。 - 手动定位下一条记录:在
fwrite之后添加了fseek(fup, ((i+1) * sizeof(employee)), SEEK_SET);,强制把文件指针移到下一条员工记录的起始位置,确保下一次fread能正确读取下一个员工。 - 清除输入缓冲区:
rewind(stdin);用来清除scanf可能残留的换行符或其他输入垃圾,避免后续读取出现异常。 - 移除冗余的初始
fread:因为循环条件里已经包含了第一次读取,不需要额外提前读一次。
这样调整后,循环就会在处理完所有员工记录后准确终止,不会出现无限循环的问题了。
内容的提问来源于stack exchange,提问作者Ofek Pintok
相关产品推荐
相关产品推荐

