C++中刷新输出缓冲区

每一个输出流都管理一个缓冲区,用来保存程序读写的数据。因此要将数据真正写到输出设备中,就需要刷新缓冲区。导致缓冲区刷新的原因大体有以下5种。

1、程序正常结束,作为main函数return操作的一部分,缓冲区被刷新。

2、当缓冲区满了的时候,会刷新缓冲区。

3、可以使用操作符endl、flush和ends来显示的刷新缓冲区。这三个都是IO库中的操作符,endl能完成换行和刷新缓冲区的工作。flush只完成刷新缓冲区的工作。而ends会向缓冲区插入一个空字符,然后刷新缓冲区。例子如下:

#include 
#include 
#include 

using namespace std;

int main()
{
	cout << "hi" << endl;
	cout << "hi" << flush;
	cout << "hi" << ends;
        cout << "hi";

	system("pause");
	return 0;
}

编译结果如下:

C++中刷新输出缓冲区_第1张图片

如上所述,ends向缓冲区插入了一个空格。我们可以观察到,例子中最后一句并没有使用任何操作符刷新缓冲区,但是依旧将缓冲区的内容输出出来了。显然不可能是因为输出缓冲区满了的缘故,程序也没有结束。这是因为当系统比较空闲的时候,会查看缓冲区的内容,如果发现有新的内容,系统就会将缓冲区的内容输出出来。不过这种刷新是不可靠的,完全取决于系统的状态,因此,我们最好使用上面的操作符来显示刷新缓冲区。

4、在每个输出操作之后,我们可以用操作符unitbuf设置流的内部状态,来清空缓冲区。设置了unitbuf操作符之后,在对缓冲区的每一次写操作之后都会进行一次flush操作。相应的,可以设置nounitbuf操作符,使该输出流恢复使用正常的系统管理的缓冲区刷新机制。默认情况下,cerr流对象是已经设置了unitbuf的,因此每次写到cerr的内容都会立即刷新。设置unitbuf和nounitbuf的方法如下:

            cout << unitbuf;      //所有的输出操作后都会立即刷新缓冲区

            cout << nounitbuf;    //回到正常的缓冲方式

5、一个输出流可能被关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流缓冲区会被刷新。默认情况下,cin和cerr都关联到cout。因此,读cin或写cerr都会导致cout的缓冲区被刷新。关联两个流可以使用tie函数,其有两个版本:

      1)不带参数,返回指向输出流的指针。如果本对象当前关联到一个输出流,则返回的就是指向这个流的指针。如果该对象没有关联到流,则返回空指针。

      2)接受一个指向ostream的指针,将自己关联到此ostream。

注意:每个流同时最多关联到一个流,但多个流可以同时关联到同一个ostream。

 

最后,我们在调试程序的时候要记住:程序出现异常终止的时候,输出缓冲区是不会刷新的(这和程序正常运行结束不一样)。也就是说数据很可能还在缓冲区中,没有输出出来。

 

你可能感兴趣的:(C/C++)