当我们对文件流进行操作的时候,它们与一个streambuf 类型的缓存(buffer)联系在一起。这个缓存(buffer)实际是一块内存空间,作为流(stream)和物理文件的媒介。例如,对于一个输出流, 每次成员函数put  (写一个单个字符)被调用,这个字符不是直接被写入该输出流所对应的物理文件中的,而是首先被插入到该流的缓存(buffer)中。

当缓存被排放出来(flush)时,它里面的所有数据或者被写入物理媒质中(如果是一个输出流的话),或者简单的被抹掉(如果是一个输入流的话)。这个过程称为同步(synchronization),它会在以下任一情况下发生:

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

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

3.用操纵符显示地刷新缓冲区,如用endl。

4.在每次输出操作执行完毕后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区。

5.可将输出流与输入流关联起来,在读输入流时将刷新其关联的输出缓冲区。

在C++中,cin, cout, cerr 分别于stdin, stdout, stderr对应的。即iostream流对象分别与cstdio对应,关系如下:

同步即表明我们可以在程序中混合用cout和printf或其他对应的流对,并不会引起流指针的混乱。可以用std::ios_base::sync_with_stdio(false)来取消这种同步,取消后,如下程序中cout和printf就不是按照预期的顺序输出

#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
for(int i = 0; i < 10; i++) {
cout << "1 ";
printf("2 ");
}
cout << endl;
printf("\n");
return 0;
}

结果为:

这表明在调用std::ios_base::sync_with_stdio(false)后,cout与stdout不再共享同一块缓冲区。它们是分别管理自己的缓冲区的。

正是因为这种同步,所以cin、cout比scanf、printf速度要慢,如果我们在使用cin、cout输入输出前加一句std::ios_base::sync_with_stdio(false),其实速度和scanf、printf差不多。原因请看

https://www.byvoid.com/blog/fast-readfile

因为默认情况下,cin是和cout绑定的,cin 会刷新cout的缓冲区,可以用函数cin.tie(0)来解绑定。所以在以下代码中应该是不会引起缓冲区刷新的:

#include <iostream>
#include <stdio.h>
using namespace std; int main(){
char buf[256];
// setbuf(stdout, buf);
cin.tie(0);
for(int i = 0; i < 10; i++)
cout << "1 " ;
cout << "\n";
int a, b;
cin >> a >> b;
cout << endl;
}

结果:

发现还是输出了缓冲区,如果我们先设置一下stdout的的缓冲区,不要默认的缓冲区试试(即在上面代码中去掉注释)结果为:

可以看到是我先输入数字1和2之后,然后执行cout <<endl ,此时刷新缓冲区,输出的11111111

具体原因可以看stackoverflow中,不过貌似也没解释太清楚

http://stackoverflow.com/questions/14052627/why-do-we-need-to-tie-cin-and-cout

我简单总结了一下,大概是说tie这个函数在绑定了cout后,保证会在cin执行之前冲刷cout的缓冲区。如果你cin.tie(0)解除了绑定,那么并不会保证cout在cin之前冲刷,但也不保证不会冲刷。

但它并没有解释为什么我设置了自己的缓冲区,它就不因为执行cin而冲刷cout的缓冲区了。

Reference:

http://www.cnblogs.com/TenosDoIt/p/3733243.html

http://blog.csdn.net/lesslie1992/article/details/14057417

C++输入输出缓冲区的刷新问题的更多相关文章

  1. c/c++ 输入输出缓冲区

    关于缓冲区的详细介绍,请参考 C++编程对缓冲区的理解 CPP的输入输出流和缓冲区 c++输出缓冲区刷新   (1)c++中cin.cout,cerr和c的stdin.stdout.stderr都是同 ...

  2. c/c++ 缓冲区的刷新

    利用string 对象查看缓冲区的变化,因为每个string对象在输入时会以空格作为分界. #include<iostream> #include<string> using ...

  3. 【C++】cout未刷新缓冲区仍会输出的问题

    众所周知,cout是一个流对象,管理一个缓冲区.当使用<<操作符输出字符串时,字符串不是直接被输出到屏幕上,而是首先被插入到该流的缓存(buffer)中.而只有当缓冲区被刷新时,字符串才会 ...

  4. 刷新PHP缓冲区

    为你的站点加速_php技巧 在当前 PHP 版本的默认配置下,“输出缓冲(Output Buffering)”是被打开的.旧版本则不是这样,在旧版本的 PHP 中,字符串在每次被输出的时候(通过 ec ...

  5. 【VS开发】【C/C++开发】printf缓冲区刷新

    printf之缓冲区小结: 今天调试程序,发现了一个有趣的现象,printf函数没有按照预期的结果输出重复的字符串,单步调试显示代码的确走到了打印屏幕的分支,没有显示不由得想到了是不是缓冲区去刷新的问 ...

  6. 【Python】【demo实验1】【Python运行时强制刷新缓冲区,输出信息】(Python3 应不存在类似情况)

    [原文] 需求:打印一颗 ”*” 休息1s 代码如下: #!/usr/bin/python #coding=utf-8 ''' 暂停1s输出 ''' import time def printStar ...

  7. C输入输出函数与缓冲区

    #转 对C语言输入输出流和缓冲区的深入理解C语言缓冲区(缓存)详解缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的 ...

  8. C语言缓冲区

    定义 缓冲区是内存空间的一部分,用于缓冲输入或输出的数据.根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区. 类型 缓冲区分为三种类型:全缓冲.行缓冲和不带缓冲. 1.全缓冲 在这种情况 ...

  9. IO库----IO类,文件输入输出,string流

    一.IO类 1.IO库类型和头文件表: 头文件 类型 iostream istream,wistream 从流读取数据 ostream,wostream 向流写入数据 iostream,wiostre ...

随机推荐

  1. MSSQL数字时间(timestamp)转换为DATETIME

    很简单: , CAST('1970-01-01 00:00:00' AS datetime))

  2. Hadoop源码的编译过程详细解读(各版本)

    说在前面的话   重新试多几次.编译过程中会出现下载某个包的时间太久,这是由于连接网站的过程中会出现假死,按ctrl+c,重新运行编译命令. 如果出现缺少了某个文件的情况,则要先清理maven(使用命 ...

  3. 用C语言实现有限状态自动机FSM

    摘要:状态机模式是一种行为模式,在<设计模式>这本书中对其有详细的描述,通过多态实现不同状态的调转行为的确是一种很好的方法,只可惜在嵌入式环境下,有时只能写纯C代码,并且还需要考虑代码的重 ...

  4. node.js在windows下的学习笔记(3)---npm

    1.什么是npm npm是Node.js的包管理器,它允许开发人员在Node.js的应用程序中创建,共享,重用模块.之前我们通过node的官网的安装程序安装了Node.js,那么npm就已经装好了的. ...

  5. rsync服务安装

    1.  rsync是开源的项目,首先去官网上下载安装包.下载地址 http://rsync.samba.org/ftp/rsync/src/ 这边我下载的是3.1.0.tar.gz 解压到/opt/r ...

  6. careercup-树与图 4.5

    4.5 实现一个函数,检查一棵二叉树是否为二叉查找树. 参考:http://blog.csdn.net/sgbfblog/article/details/7771096 C++实现代码: #inclu ...

  7. android 程序打开第三方程序

    因为在开发过程中需要开启扫描第三方程序,并且点击启动的效果,所以对这个功能进行了实现,并且分享出来个大家. 之前看到网上说需要获取包名和类名,然后通过  intent 才能打开这个程序,其实不必要这样 ...

  8. IPv6 neighbor discovery

    IPv6 neighbor discovery By stretch | Thursday, August 28, 2008 at 5:03 a.m. UTC Neighbor Discovery P ...

  9. 页面常见效果js实现

    2015.12.2 页面常见效果js实现 [有没有觉得很坑,[笑哭,邮箱写上]] 复习: Js内置对象: 1.浏览器对象 window document history location event  ...

  10. [置顶] linux第二天,g++,gcc,ps,cat,sort,grep,kill,less,ls -l ,

    33.less sample.txt 分页输出文件内容到屏幕 34./search content (搜索内容) 可以将文档中有searchcontent 的行输出到屏幕 35.grep scienc ...