1

以下程序是有效的 C 程序吗?

#include <stdio.h>

int main()
{
    fwrite("x", 1, 1, stderr);
    fflush(stderr);
    fgetc(stderr);
    fwrite("y", 1, 1, stderr);
    return 0;
}

请注意,我尝试从标准错误中读取。

当我在 Visual C++ 2008 中编译并运行它时,我得到以下输出:

xy

这是有道理的。但是,当我将 stderr 重定向到一个文件 ( test.exe 2> foo.txt) 时,我会看到一个“调试断言失败”窗口,并显示以下消息:“不一致的流计数。在连续读取和写入之间刷新”。fflush在读取和写入之间添加 a确实可以解决问题。(这发生在调试版本中。在发布版本中,第二次写入静默失败)。

这种行为是否正确,或者这是编译器库错误?我在任何地方都找不到任何描述何时在 C 中读取或写入是非法的规则。

4

1 回答 1

3

C99 在 7.19.5.3 ( fopen) 第 6 段中说:

当以更新模式打开文件时('+'作为上述mode参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出。但是,在没有中间调用函数[...]的情况下,输出不得直接跟在输入之后fflush,并且在没有中间调用文件定位函数的情况下,输入不得直接跟在输出之后,除非输入操作遇到 end-of -文件。

恭喜你在实践中发现了这个极端案例。库实现是完全正确的,因为您违反了上面引用的应。

顺便说一句,从stderr. stdin当和stdout被重定向并且没有可用的终端时,这很有用。尽管 C99 不保证它是可读的,但我记得在类似 POSIX 的系统上确实做到了这一点。

于 2010-07-08T19:16:09.603 回答