[英]Why does fgetc move the file position indicator backwards?
当我在Windows(Visual Studio 15)上构建时,在freeBSD系统上运行良好的程序失败。 它在这里陷入无尽的循环:
//...
while (1) {
if ('@' == fgetc(f)) {
// we do some stuff here. irrelevant for stackoverflow question
break;
}
fseek(f, -1, SEEK_CUR);
if (0 != fseek(f, -1, SEEK_CUR)) {
// Beginning of file.
break;
}
}
//...
仔细观察(通过添加一堆fgetpos()调用),我发现fgetc 向后移动文件位置指示器。 因此,它会错过文件的开头,如果它们与末尾的位置不是3的倍数,则会丢失一些“ @”。
我注意到这仅在使用以下文件f打开时发生
fopen(filename, "a+");
//text mode read/append
当我将其更改为
fopen(filename, "ab+");
//binary mode read/append
然后一切都会按预期进行。 我认为对于我的代码而言,始终使用二进制模式是安全的。 但是仍然存在两个问题:
引用C11 7.21.9.2的fseek
函数:
对于文本流,offset应该为零,或者offset应该是对与同一文件相关联的流上的ftell函数的较早成功调用返回的值,并且whence应该为SEEK_SET。
C标准不包括在文本模式下打开的流上使用SEEK_CUR
的whence参数调用fseek
。 以二进制模式打开文件似乎是一个更好的选择。
fgetpos()
返回的值作为文件中的偏移量可能没有意义,它仅应作为参数传递给fsetpos()
。
通常,您应该尝试更改算法,以避免依赖于流中的向后搜索,尤其是依赖fseek()
错误似乎不可靠。 而是使用ftell()
或fgetpos()
将位置保存在fgetc()
之前,并在需要时使用fseek(pos, SEEK_SET, fp)
或fsetpos()
恢复该位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.