令人困惑的Cygwin代码流序列

时间:2017-09-14 06:58:17

标签: c cygwin

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先执行并等待输入:: enter image description here

但是当我在Cygwin终端下运行相同的exe时,它等待输入,然后printf执行::

enter image description here

为什么会有这种差异?

编辑:: \n语句中的字符串附加printf,行为保持不变::

enter image description here

1 个答案:

答案 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没有被缓冲:: enter image description here

mintty.exe相同的exe,stdout被缓冲:: enter image description here

现在的问题是,

  • 为什么stdout在一个中没有缓冲而在另一个上缓冲?
  

正如您可以看到两者上的tty输出一样,bash显示为控制台会话   /dev/cons0,而mintty显示为伪终端会话   /dev/pty0

所以,

  • 它如何回答无缓冲和缓冲的stdout问题?
  

我的浏览重新搜索让我here,说明,如果我输入tty   在相应的Cygwin窗口中,我看到minttyxterm都是   伪终端,而bash是一个控制台会话 - 我相信   procServ使用forkpty()。所以我认为归结为Windows处理   一个Cygwin pty作为非交互式,因此缓冲stdout和。{   stderr

我不确定,这是多么精确但是,这似乎是对这种行为的实际和最好的解释。

Section 7.9.13/7 of c99所述:

  

在程序启动时,预定义了三个文本流,不需要   明确打开 - 标准输入(用于读取传统输入),   标准输出(用于写入常规输出)和标准错误   (用于编写诊断输出)。

     

最初打开时,标准错误流未完全缓冲;   标准输入和标准输出流完全缓冲,如果   并且只有当流可以被确定为不参考时   互动设备

*大胆的重点是我的。