1

我正在测试一个用 C 编写的非常基本的程序,整个程序都包含在下面。在尝试执行 TCC 生成的可执行文件时,我注意到在实际看到任何 printf() 调用的输出之前,我需要为每个连续的 fgets() 输入输入。

这非常令人困惑,因此我决定尝试在标准 Windows 控制台上运行可执行文件。它运行完美,输入和输出提示以正确的顺序显示。

但是,我注意到如果我用 GCC 编译程序,它可以在 Cygwin 编译的终端上正常工作(薄荷,虽然我用 rxvt 得到了相同的结果)。

谁能解释为什么会发生这种情况,以及如何阻止它发生?我想独立于 Cygwin 编译我的程序,同时仍然使用基于 Cygwin 的终端。

谢谢!

int main()
{
        char something[12];

        printf("This printf() should be outputted before you are prompted for input: ");

        fgets(something, sizeof something, stdin);

        printf("You entered, %s", something);
}
4

3 回答 3

2

这取决于标准输入和标准输出的缓冲。我不确定 C 标准对此有什么看法(在 C++ 中,流默认绑定),但您可以自己刷新标准输出:

 fflush( stdout );

在调用 printf 之后。

于 2011-04-23T08:03:33.523 回答
1

标准输出流通常是行缓冲的,即当您打印换行符时缓冲区会被刷新。

您可以使用以下命令显式刷新它:

fflush(stdout);

您可以使用以下命令关闭给定流s的缓冲:

setvbuf(s, NULL, _IONBF, 0);

有关详细信息,请参阅setvbuf() 的联机帮助页

于 2011-04-23T08:38:17.073 回答
1

Mintty 和 rxvt 是基于 Unix伪终端设备的终端仿真器。Cygwin 基于Windows 管道实现这些。

当您使用 Cygwin gcc 编译程序时,它会链接到 Cygwin DLL,其中包含使连接到终端的流像在 Unix 系统上一样工作的所有魔法,这意味着默认情况下是行缓冲。

然而,当你用 tcc 编译程序时,你创建了一个本地 Windows 程序,它只看到底层的 Windows 管道。在 Microsoft C 库中,连接到管道的流默认情况下是完全缓冲的,这就是为什么fflush(stdout)使用帮助显式刷新或禁用缓冲的原因setvbuf(stdout, NULL, _IONBF, 0)。MS 的 C 库不支持行缓冲。

于 2011-04-23T10:50:19.147 回答