【发布时间】:2017-07-14 19:36:23
【问题描述】:
我了解,endl 和 \n 之类的问题已在 SO 上得到多次回答。但他们只提到endl 能够将缓冲区刷新到stdout,而\n 不能。
所以,我对刷新缓冲区的理解是,给定的输入存储在缓冲区中,并且仅在遇到endl 或某些显式flush 函数时才传递到stdout。如果是这样,我希望以下代码:
#include <iostream>
#include <unistd.h>
int main(void)
{
std::cout << "Hello\nworld";
sleep(2);
std::cout << std::endl;
return 0;
}
显示:
2 秒后
Hello
World
但实际输出是:
Hello
2 秒后
World
为什么会这样?
\n 不应该也存储在缓冲区中,并且仅当遇到 endl 时,缓冲区才会被刷新/显示到 stdout,但据我观察,\n 的行为方式与endl。
【问题讨论】:
-
这取决于
cout的去向。如果它进入终端(“交互式设备”),那么它不能被完全缓冲——它通常是行缓冲的,这意味着字符在打印换行符之后出现,或者理论上可以是无缓冲的。如果流向管道、文件或其他非交互目的地,endl会强制数据输出,即使流已完全缓冲,通常也是如此。 -
我还想知道我是否既没有提供换行符也没有提供
endl,一旦到达程序末尾,输出是否会显示在stdout上,我知道它适用于终端,但它适用于所有类型的stdout吗? -
是的,当文件流在程序(正常)结束时关闭时,挂起的输出将被刷新。当缓冲区已满时,它也会被刷新。如果程序中止,挂起的输出通常不会被刷新。
-
@JonathanLeffler:处理交互流输出的 C++ 方法是让
std::cin成为tie()d 到std::cout:每当访问std::cin时,std::cout就会被刷新。对于写入stdout的 C++ 程序,观察到行缓冲区行为的实际原因是与 stdio 的同步,显然,对于使用标准流的任何理智的 C++ 程序,该同步被禁用,否则程序会被不合理地减慢。