在C++中,每个I/O对象管理一个缓冲区,用于存储程序读写的数据。本文将对输出缓冲区的管理进行简单的讲解。

举一个简单的例子:

myOs << "Please enter a value: ";

系统将字符串字面值存储在与流myOs关联的缓冲区中。(至于什么是流、缓冲区,可以阅读:C++ Primer Plus(Fifth Edition), Stephen Prata一书中的介绍)。下面几种情况将导致缓冲区的内容被刷新,即写入到真实的输出设备或者文件:

(1) 程序正常结束。作为main()返回工作的一部分,将清空所有输出缓存区;

注意:

如果程序不正常结束,输出缓冲区将不会刷新。在尝试调试已经崩溃的程序时,通常会根据最后的输出找出程序发生错误的区域。如果崩溃出现在某个特定的输出语句后面,则可能是在程序的这个位置之后出错。

(2) 在一些不确定的时候,缓冲区可能已经满了,在这种情况下,缓冲区将会在写下一个值前刷新;

(3) 使用操作符显示地刷新缓冲区,例如行结束符std::endl

注意:

a) std::endl操作符的作用有两个:输出一个换行符并刷新缓冲区。而C中经常使用的换行符\n,并不具备刷新缓冲区的作用。

b) 如果仅因为缓冲区没有刷新,程序员将浪费大量时间跟踪调试并没有执行的代码。基于这个原因,输出时应更多使用std::endl而非\n,使用std::endl则不必担心程序崩溃时输出是否悬而未决(即还留在缓冲区,未输出到设备中)。

c) 除了std::endl操作符外,C++还提供了另外两种操作符:std::flushstd::ends,前者用于刷新流,但不会在输出中添加任何字符,后者比较少用到,会在缓冲区中插入空字符null然后刷新。

std::cout << "Hello world!" << std::flush; // flushes the buffer; adds no data
std::cout << "Hello world!" << std::ends; // inserts a null, then flushes the buffer
std::cout << "Hello world!" << std::endl; // inserts a newline, then flushes the buffer

(4) 在每次输出操作完成后,使用unitbuf操作符设置流的内部状态,从而清空缓冲区;

注意: 如果需要刷新所有输出,最好使用unitbuf操作符。这个操作符会在每次执行完流输出时刷新流,并且不会在输出中添加任何字符:

std::cout << std::unitbuf << "first" << "second" << std::nounitbuf;
// equal to the follow:
std::cout << "first" << std::flush << "second" << std::flush;

其中,std::nounitbuf是结束std::unitbuf的作用,使输出流恢复到正常的、由系统管理的缓冲区刷新方式。

(5) 可将输出流与输入流关联tie起来。在这种情况下,任何读输入流的尝试都将首先刷新其输出流关联的缓冲区。而标准库中提供了将std::coutstd::cin绑在一起的方法:tie

注意:

a) tie函数可用istream(例如:ifstream)或ostream(例如:ofstream)对象调用,使用一个指向ostream对象的指针形参。调用tie函数时,将实参流绑在调用该函数的对象上。如果一个流调用tie函数将其本身绑在传递给tieostream实参对象上,则该流上的任何I/O操作都会刷新实参所关联的缓冲区:

/* the library ties std::cin and std::cout */
std::cin.tie( &std::cout );
ostream *old_tie = std::cin.tie(); /*
break tie to std::cout, std::cout no longer flushed
when std::cin is read
*/
std::cin.tie( 0 ); /* restablish normal tie between std::cin and std::cout */
std::cin.tie( old_tie );

一个ostream对象每次只能与一个istream对象绑在一起。如果在调用tie函数时传递实参0,则打破该流上已存在的捆绑。

b) 交互式系统通常应确保它们的输入和输出流是捆绑在一起的。这样做意味着可以保证任何输入,包括给用户的提示,都在试图读之前输出。

参考文献:《C++ Primer中文版(第四版)》,Stanley B. Lippman 等著。

C++ 输出缓冲区的管理的更多相关文章

  1. 深入理解php的输出缓冲区(output buffer)

    这篇文章是翻译自Julien Pauli的博客文章PHP output buffer in deep,Julien是PHP源码的资深开发和维护人员.这篇文章从多个方面讲解了PHP中的输出缓冲区以及怎么 ...

  2. PHP的输出缓冲区(转)

    什么是缓冲区?简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料.其实缓冲区最本质的作用就是,协调 ...

  3. PHP的输出缓冲区

    什么是缓冲区?简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料.其实缓冲区最本质的作用就是,协调 ...

  4. zlib 压缩输出缓冲区 overflow 问题

    [TOC] 问题 后台服务传包太大时,我们框架可以使用 zlib 库对响应进行压缩:在这次服务调试过程中,使用 zlib compress2 以 Z_BEST_COMPRESSION 模式进行压缩时, ...

  5. python输出缓冲区的问题

    碰到的问题,一段代码,print在前,log的在后,查看日志中log的反而在前面.是python输出缓冲区的问题. python输出缓冲区要满 4k 才写入文件,除非禁用缓存或者强制输出或者程序结束. ...

  6. PHP基础之输出缓冲区基本概念、原理分析

    一.概念 在PHP运行的过程中,可以将会产生输出的函数或操作结果暂时保存在PHP的缓冲区,只有当缓冲区满了.或者PHP运行完毕.或者在必要时候进行输出,才会将数据输出到浏览器,此缓冲数据的区域称为PH ...

  7. 多线程爬虫Java调用wget下载文件,独立线程读取输出缓冲区

    写了个抓取appstore的,要抓取大量的app,本来是用httpclient,但是效果不理想,于是直接调用wget下载,但是由于标准输出.错误输出的原因会导致卡住,另外wget也会莫名的卡住. 所以 ...

  8. 控制台输出<迷你DVD管理>

    使用顺序.选择.循环.跳转语句 数组 功能实现菜单显示和切换 输入的数字不符合要求直接退出程序 用户可以选择新增.查看. 删除.借出.归还.退出 思路分析 使用switch语句实现菜单选择 使用do- ...

  9. Redis-输入输出缓冲区

    一.client list id:客户端连接的唯一标识,这个id是随着Redis的连接自增的,重启Redis后会重置为0addr:客户端连接的ip和端口fd:socket的文件描述符,与lsof命令结 ...

随机推荐

  1. Codeforces 845A. Chess Tourney 思路:简单逻辑题

    题目: 题意:输入一个整数n,接着输入2*n个数字,代表2*n个选手的实力.    实力值大的选手可以赢实力值小的选手,实力值相同则都有可能赢.    叫你把这2*n个选手分成2个有n个选手的队伍. ...

  2. JavaScript学习——使用JS完成注册页面表单校验

    1.步骤分析 第一步:确定事件(onsubmit)并为其绑定一个函数 第二步:书写这个函数(获取用户输入的数据<获取数据时需要在指定位置定义一个 id>) 第三步:对用户输入的数据进行判断 ...

  3. shell-1.shell概述、2.shell脚本执行方式

    目录

  4. java 实现多线程 3种方式

    java实现多线程可以有以下三种方式: (1)继承Thread 类,重写其run()方法: (2)实现Runnable接口,实现其run() 方法: (3) 实现Callable 接口,重写call( ...

  5. jQuery基本操作以及与js的一些比较

    jQuery和js主要区别在DOM操作 用jQuery必须先引进jQuery.js文件 js和jQuery写在哪: 1.标签里面 常用就是方法调用 2.写在script标签里面 3.js文件 dom操 ...

  6. Url 简单讲解

    eg: http://sb.test.com/login?name=liming&password=twotigers 协议 http https ftp 域名 sb.test.com 则是域 ...

  7. (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树

    题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...

  8. wackoPicko 渗透平台的安装

    2016-05-17 wackoPicko 的介绍及下载地址        https://github.com/adamdoupe/WackoPicko#from=codefrom.com 首先我们 ...

  9. IDEA中编写脚本并运行shell脚本

    IDEA中编写脚本并运行shell脚本     来自 <https://blog.csdn.net/u012443641/article/details/81295999>

  10. 【图灵杯 J】简单的变位词

    Description 变位词是指改变某个词的字母顺序后构成的新词.蔡老板最近沉迷研究变位词并给你扔了一道题: 给你一些单词,让你把里面的变位词分组找出来.互为变位词的归为一组,最后输出含有变位词最多 ...