C中有一个非常简单的程序(在Cygwin上用gcc构建)::
// This program is a tutorial to Stack-based overflow, that's why "gets"
#include <stdio.h>
void test()
{
char buff[4];
printf("Some input: ");
gets(buff);
puts(buff);
}
int main(int argc, char** argv)
{
test();
return 0;
}
现在当我在Windows控制台上运行时,printf
先执行并等待输入::
但是当我在Cygwin终端下运行相同的exe时,它等待输入,然后printf
执行::
为什么会有这种差异?
编辑:: \n
语句中的字符串附加printf
,行为保持不变::
答案 0 :(得分:0)
因此,经过一些阅读和研究,我总结了这种行为的最终理论。
简短答案:: stdout
已缓冲,因此执行
void test()
{
char buff[4];
setvbuf(stdout, NULL, _IONBF, 0); // <--- setting stdout to _IONBF
printf("Some input: ");
gets(buff);
puts(buff);
}
在将任何内容打印到控制台之前,
void test()
{
char buff[4];
printf("Some input: ");
fflush(stdout); // <--- force the stdout to flush
gets(buff);
puts(buff);
}
在printf
语句解决问题后。
长答案
当我使用Bash.exe
运行相同的exe时,stdout没有被缓冲::
现在的问题是,
stdout
在一个中没有缓冲而在另一个上缓冲?正如您可以看到两者上的
tty
输出一样,bash显示为控制台会话/dev/cons0
,而mintty显示为伪终端会话/dev/pty0
。
所以,
我的浏览重新搜索让我here,说明,如果我输入
tty
在相应的Cygwin窗口中,我看到mintty
和xterm
都是 伪终端,而bash
是一个控制台会话 - 我相信procServ
使用forkpty()
。所以我认为归结为Windows处理 一个Cygwin pty作为非交互式,因此缓冲stdout
和。{stderr
。强>
我不确定,这是多么精确但是,这似乎是对这种行为的实际和最好的解释。
据Section 7.9.13/7 of c99
所述:
在程序启动时,预定义了三个文本流,不需要 明确打开 - 标准输入(用于读取传统输入), 标准输出(用于写入常规输出)和标准错误 (用于编写诊断输出)。
最初打开时,标准错误流未完全缓冲; 标准输入和标准输出流完全缓冲,如果 并且只有当流可以被确定为不参考时 互动设备。
*大胆的重点是我的。