繁体   English   中英

为什么fgetc向后移动文件位置指示器?

[英]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.2fseek函数:

对于文本流,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM