printf() 在 scanf() 之后以行缓冲模式将不带换行符的字符串打印到标准输出

printf() prints string without newline to stdout in line buffer mode after scanf()

我知道大多数终端默认处于行缓冲模式。即输出被缓冲并且在遇到换行符之前不被定向到标准输出。

所以我希望这不会打印任何内容(至少在缓冲区填满之前):

int main() {
    while(1) {
        printf("Haha");
        sleep(1);
    }
    return 0;
}

的确是短时间内什么都不打印。

如果我想每秒打印 "Haha",我可以 printf("Haha\n") 或在 printf 之后执行 fflush(stdout)。 (我知道这不是那么便携,但它仍然是一个解决方案)

现在我想起了非常经典的 scanf 程序(我添加了 while(1) 循环以防止在程序退出时刷新缓冲区):

int main() {
    char char_in;
    while(1) {
        printf("Haha. Input sth here: ");
        scanf("%c", &char_in);
    }
    return 0;
}

现在程序打印 Haha. Input sth here:(并等待我的输入)。如果我删除 scanf 语句,它不在这里。为什么会这样?

谢谢。

Now the program prints Haha. Input sth here: (and wait for my input). It is not here if I remove the scanf statement. Why is that so?

因为标准 (N1570 .. "almost C11") 是这么说的,§5.1.2.3/6(强调我的):

The least requirements on a conforming implementation are:

[..]

  • The input and output dynamics of interactive devices shall take place as specified in 7.21.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.

[..]

即使您的输出不包含换行符并且被发送到缓冲的行 stdout,它 必须 在您的程序被允许等待输入之前出现.这是因为 stdoutstdin 连接到终端,因此(注意:这是实现定义的!)标准称为 "interactive devices" .