Featured image of post C++ IO 缓冲区

C++ IO 缓冲区

在C++中,输入输出流(IO流)是程序与外部设备(如屏幕、文件)交互的桥梁。

前言

在C++中,输入输出流(IO流)是程序与外部设备(如屏幕、文件)交互的桥梁。为了提高效率,输出流通常会使用缓冲区暂存数据,避免每次输出都直接访问设备带来的性能开销。

正文

输出缓冲区的作用与刷新机制

每个输出流对象都维护一个缓冲区,用于暂存待输出的数据。程序执行输出语句时,数据首先写入缓冲区,而非立即写入设备或文件。缓冲区的存在显著提升了程序性能,减少了对硬件设备的频繁访问。

缓冲区何时被刷新(即数据真正写到输出设备或文件)?

主要有以下几种情况:

  • 程序正常结束(如main函数返回)时,系统自动刷新缓冲区。
  • 缓冲区满时,自动触发刷新。
  • 使用特定操纵符显式刷新,如endlflushends
  • 通过unitbuf操纵符设置流的状态,使每次输出后自动刷新。
  • 输入流与输出流关联时,读取输入流会先刷新关联的输出流缓冲区。

刷新输出缓冲区

刷新操纵符:

  • endl:输出换行符并刷新缓冲区。
  • flush:仅刷新缓冲区,不输出额外字符。
  • ends:输出空字符并刷新缓冲区。

示例:

1
2
3
cout << "hello" << endl;  // 输出hello和换行,刷新缓冲区
cout << "hello" << flush; // 输出hello,刷新缓冲区但不换行
cout << "hello" << ends;  // 输出hello和空字符,刷新缓冲区

unitbuf操纵符

通过unitbuf可以设置流为“每次输出后立即刷新缓冲区”的模式,适合需要实时输出的场景。对应的nounitbuf则恢复默认的缓冲策略。

1
2
3
cout << unitbuf;   // 开启自动刷新
cout << "data";    // 输出后立即刷新
cout << nounitbuf; // 恢复默认缓冲

需要注意的是,标准错误流cerr默认启用了unitbuf,保证错误信息及时输出。

[!note]

如果程序异常终止(崩溃),缓冲区不会被刷新,可能导致部分输出丢失。

总结

输出缓冲区是C++ IO库中提升性能的重要机制,但合理管理缓冲区的刷新同样关键。通过使用endlflushends等操纵符,或利用unitbuf设置自动刷新,可以确保程序输出及时、准确。

《C++ Primer》

Licensed under CC BY-NC-SA 4.0