为什么cerr刷新cout的缓冲区

wil*_*rcs 7 c++

#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;
}
Run Code Online (Sandbox Code Playgroud)

在我编译并运行上面的程序之后,它的输出是:

hello couthello cerr
All   done 
Run Code Online (Sandbox Code Playgroud)

但我认为它应该是:

hello cerrhello cout
All   done 
Run Code Online (Sandbox Code Playgroud)

我想知道,为什么要cerr冲洗缓冲区cout

Bo *_*son 8

这是设计的.

这两个cincerr是绑cout,并呼吁cout.flush()之前的任何自身的运作.

这个想法可能是输入和输出应该以正确的顺序发生.


Jam*_*nze 8

首先,只要感觉到流,就允许流冲洗.我有可能iostream的某些实现在输出到交互式设备时会改变缓冲策略.除非您有意在两个流的输出之间进行刷新,否则它们出现的顺序或多或少都未指定; 你可以算的上是一个单一的<<,以cerr不会有字符从cout插入到它.在你的情况下,实现同步cout,并cerr以某种方式.(您可能希望看到如果将其输出重定向到不同的文件会发生什么.或者对于相同的非交互式文件 - C++在交互设备和其他设备之间没有区别,但C确实如此,我希望大多数C++实现遵循C in这方面.)

FWIW,有关订单的两项保证是:

  • cout与之相关cin,所以任何阅读的尝试cin都会冲洗cout,并且
  • cerrunitbuf设置,因此它将在每个<<运算符的末尾刷新.

我认为,后者背后的想法是获得类似于C的行缓冲的东西,C++不直接支持 - 尽管如果你使用std::endl,你会得到与行缓冲相同的效果.