C - fputs在读取到文件末尾后返回-1



我在Windows上遇到一些文件写入失败的问题。我将其简化为以下示例:

FILE* f = fopen("test.out", "r+b");
fseek(f, -1, SEEK_END); // one byte before the end
printf("read byte: %cn", fgetc(f)); // read the last byte; now at the end
printf("attempting write: %dn", fputs("text", f));

正确输出test.out的最后一个字节,但fputs失败并返回-1。这些类似的例子都很好:

  • 不读

    FILE* f = fopen("test.out", "r+b");
    fseek(f, 0, SEEK_END); // this is where I ended up after the fgetc() above
    printf("attempting write: %dn", fputs("text", f));
    
  • 读取结束后查找(即使我们已经在那里)

    FILE* f = fopen("test.out", "r+b");
    fseek(f, -1, SEEK_END);
    printf("read byte: %cn", fgetc(f));
    fseek(f, 0, SEEK_END);
    printf("attempting write: %dn", fputs("text", f));
    
  • 寻找我们已经到达的确切位置

    FILE* f = fopen("test.out", "r+b");
    fseek(f, -1, SEEK_END);
    printf("read byte: %cn", fgetc(f));
    fseek(f, ftell(f), SEEK_SET);
    printf("attempting write: %dn", fputs("text", f));
    
  • 读取,但不是最后一个字节

    FILE* f = fopen("test.out", "r+b");
    fseek(f, -2, SEEK_END); // two bytes before the end
    printf("read byte: %cn", fgetc(f)); // read the penultimate byte
    printf("attempting write: %dn", fputs("text", f));
    
  • 读取超过结束(…)

    FILE* f = fopen("test.out", "r+b");
    fseek(f, -1, SEEK_END); // one byte before the end
    printf("read byte: %cn", fgetc(f)); // read the last byte; now at the end
    printf("read byte: %cn", fgetc(f)); // read a garbage byte
    printf("attempting write: %dn", fputs("text", f));
    

这些似乎都表示流错误或eof问题,但ferror(f)feof(f)都返回0,直到失败的fputs()。之后,ferror(f)是非零,但errno是0,所以我不知道问题是什么

我只在Windows上看到这个,在Visual Studio 2008和GCC 4.7.2 (MinGW)中。在Linux上同样的代码运行没有错误

C标准要求在从"读模式"切换到"写模式"或反之亦然时执行seek,除非在某些通常不值得枚举的特殊情况之后。

一个实现(比如我几年前为bsd编写的那个,或者Linux的那个)可以比需要的更宽容,使你的代码"正常工作"。(这真的很简单,您只需要在实现中保留两个单独的计数器,而不是一个合并的计数器。)但是标准并不要求实现是友好的,Windows的也不是。

相关内容

  • 没有找到相关文章

最新更新