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

标签 c file-io stream

我在 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/

相关文章:

将结构中的字符与用户输入进行比较

c - 如何在 Tensorflow Lite(实验 C API)中创建输入张量并与解释器一起使用?

c++ - 读取文件时进入无限循环

video - 如果您必须添加对一种视频文件格式和编解码器的支持,您会选择哪一种?

c# - 流式传输 IEnumerable

C++错误 "too few arguments to function"

c - 字节数组上的 Printf

video - 直播视频码率计算公式

linux - 尾 block 会附加到 Linux 内核中的文件吗?

camera - 嵌入网站的 RTSP 到 HTTP MJPEG 转码