我在 Windows 上遇到文件写入失败的问题。我将它简化为这个例子:
FILE* f = fopen("test.out", "r+b");
fseek(f, -1, SEEK_END); // one byte before the end
printf("read byte: %c\n", fgetc(f)); // read the last byte; now at the end
printf("attempting write: %d\n", 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: %d\n", fputs("text", f));
读完再找到底(即使我们已经到了)
FILE* f = fopen("test.out", "r+b"); fseek(f, -1, SEEK_END); printf("read byte: %c\n", fgetc(f)); fseek(f, 0, SEEK_END); printf("attempting write: %d\n", fputs("text", f));
寻找我们已经所在的位置
FILE* f = fopen("test.out", "r+b"); fseek(f, -1, SEEK_END); printf("read byte: %c\n", fgetc(f)); fseek(f, ftell(f), SEEK_SET); printf("attempting write: %d\n", fputs("text", f));
读取,但不是最后一个字节
FILE* f = fopen("test.out", "r+b"); fseek(f, -2, SEEK_END); // two bytes before the end printf("read byte: %c\n", fgetc(f)); // read the penultimate byte printf("attempting write: %d\n", fputs("text", f));
读完 (...)
FILE* f = fopen("test.out", "r+b"); fseek(f, -1, SEEK_END); // one byte before the end printf("read byte: %c\n", fgetc(f)); // read the last byte; now at the end printf("read byte: %c\n", fgetc(f)); // read a garbage byte printf("attempting write: %d\n", 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 标准要求您在从“读取模式”切换到“写入模式”或从“读取模式”切换到“写入模式”时进行查找,除非在通常不值得列举的某些其他特殊情况之后。
实现(例如我多年前为 BSD 或 Linux 编写的实现)可能比要求的更宽容,使您的代码“正常工作”。 (这真的很容易,您只需要在实现内部保留两个单独的计数器而不是一个组合计数器。)但是标准不要求实现友好,而 Windows 则不需要。
关于c - fputs 读取到文件末尾后返回-1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17095681/