#include <iostream>
using std::cout;
using std::endl;
using std::cerr;
#include <cstdio>
int main( )
{
char pbuffer[BUFSIZ];
setbuf(stdout, pbuffer);
cout << "hello cout" ;
sleep(5);
cerr << "hello cerr";
sleep(5);
cout << "\nAll done " << endl;
sleep(5);
return 0;
}
编译并运行上面的程序后,它的输出是:
hello couthello cerr
All done
但我认为应该是:
hello cerrhello cout
All done
我想知道,为什么cerr
会刷新cout
的缓冲区?
答案 0 :(得分:7)
这是设计的。
cin
和cerr
都绑定到cout
,并在执行任何操作之前调用cout.flush()。
这个想法可能是输入和输出应该以正确的顺序发生。
答案 1 :(得分:7)
首先,只要感觉到流,就允许流冲洗。我有可能iostream的某些实现在输出到交互式设备时会改变缓冲策略。除非您有意在两个流的输出之间进行刷新,否则它们出现的顺序或多或少都未指定;您可以依赖的是,<<
到cerr
的单个cout
不会插入cout
中的字符。在您的情况下,实施正在以某种方式同步cerr
和cout
。 (您可能希望看到如果将其输出重定向到不同的文件会发生什么。或者对于相同的非交互式文件 - C ++在交互设备和其他设备之间没有区别,但C确实如此,我希望大多数C ++实现遵循C in这方面。)
FWIW,有关订单的两项保证是:
cin
与cin
绑定,因此任何阅读cout
的尝试都会刷新cerr
,unitbuf
已设置<<
,因此会在每个std::endl
运算符的末尾刷新。我认为,后者背后的想法是获得类似于C的行缓冲的东西,C ++不直接支持 - 尽管如果你使用{{1}},你会得到与行缓冲相同的效果。 / p>