【问题标题】:printf() prints string without newline to stdout in line buffer mode after scanf()printf() 在 scanf() 之后以行缓冲区模式将不带换行符的字符串打印到标准输出
【发布时间】:2017-01-23 00:16:30
【问题描述】:

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

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

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

它确实在短时间内什么也不打印。

如果我想每秒打印一次“哈哈”,我可以在 printf 之后 printf("Haha\n")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 语句,它就不在这里了。为什么会这样?

谢谢。

【问题讨论】:

  • 你能显示整体输出吗?
  • fflush(stdout) 很好且便携;有问题的是Using fflush(stdin)
  • scanf() 从交互式设备读取数据时,如果标准输出也发送到交互式设备,它通常会自动运行fflush(stdout)(将“终端”视为“交互式设备”)。标准既没有要求也没有禁止 - 但同步很常见,并且有大量的历史先例。 ——我相信这个问题之前已经被问过(并回答过)。现在去找副本……可能是一种愤怒的练习。 (此外,您最好使用 scanf(" %c", &char_in) 在两个方面做得更好——传递一个指针,并像之前的换行符一样跳过空格)。
  • @LordSalforis 我添加了一些。不过不多。告诉我你是否想添加更具体的东西。
  • ...prevent buffer flushing on program exit 是什么意思?

标签: c stdio


【解决方案1】:

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

因为标准(N1570 ..“几乎 C11”)是这样说的,§5.1.2.3/6(强调我的):

对一致性实现的最低要求是:

[..]

  • 交互式设备的输入和输出动态应按照 7.21.3 中的规定进行。这些要求的目的是尽快出现无缓冲或行缓冲的输出,以确保在程序等待输入之前实际出现提示消息

[..]

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

【讨论】:

    猜你喜欢
    • 2021-05-12
    相关资源
    最近更新 更多