搜索
查看: 1062|回复: 0

[分享] C与C++输入输出缓冲的一些操作与特性

[复制链接]

该用户从未签到

2586

主题

2613

帖子

0

蝴蝶豆

版主

最后登录
2021-3-16
发表于 2021-3-5 21:04:56 | 显示全部楼层 |阅读模式
【导读】:本文介绍C与C++输入输出缓冲的一些操作与特性。

以下是正文

(1)c++中cin、cout,cerr和c的stdin、stdout、stderr都是同步的,即iostream 对象和 and cstdio流是同步的,同步关系如下:
微信图片_20210305210438.png
同步即表明我们可以在程序中混合用cout和printf或其他对应的流对。可以用std::ios_base::sync_with_stdio(false)来取消这种同步,取消后,如下程序中cout和printf就不是按照预期的顺序输出

  1. std::ios_base::sync_with_stdio(false);
  2. for(int i = 0 ; i < 10; i++)
  3. {
  4.      cout<<"1 ";
  5.      printf("2 ");
  6. }
复制代码

windows下输出是:

  1. 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
复制代码

linux下是:

  1. 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
复制代码

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

  1. for(int i = 0 ; i < 10; i++)
  2. {
  3.     cout<<"1 ";
  4. }
  5.     while(1);
复制代码

以上程序在windows下立即输出10个1,linux下不输出。说明windows下默认cout是无缓冲的(window可以通过cout<<stdout->bufsiz来查看缓冲区大小,windows不能这么做),linux下是有缓冲的。(cout换成printf也是一样)
(3)我们可以通过函数setbuf 和 setvbuf 自己设置输入输出流的缓冲区,需要注意的是不管程序中申请的的缓冲区实际大小为多少,setbuf都将缓冲区设置的大小为BUFSIZ(这个宏在windows下是512,ubuntu下是1024), setvbuf则可以设置缓冲区大小以及缓冲区的模式(行缓冲、全缓冲、无缓冲),需要注意的是这两个函数设置的是c的输入输出缓冲区,因为c++和c的缓冲区是同步的,所有该函数会对c++有影响

  1. char buf[1024];
  2. setbuf(stdout, buf);
  3. for(int i = 0 ; i < 10; i++)
  4. {
  5.     cout<<"1 ";
  6. }
  7. while(1);
复制代码

此时windows和linux下都没有输出1
(4)因为默认情况下,cin是和cout绑定的,cin 会刷新cout的缓冲区,可以用函数cin.tie(0)来解绑定。所以在上面代买的基础上,在while(1); 前面加上:int a; cin>>a; 此时所有的1就可以输出了。

  1. char buf[1024];
  2. setbuf(stdout, buf);
  3. for(int i = 0 ; i < 10; i++)
  4. {
  5.     cout<<"1 ";
  6. }
  7. int a; cin>>a;
  8. while(1);
复制代码

加上cin.tie(0)后,以下的代码没有输出1,因为cin已经和cout解绑定了,cin刷新不了cout的缓冲区。(可以cin.tie(&cout)来绑定,注意cout没有tie方法)

  1. char buf[1024];
  2. setbuf(stdout, buf);
  3. cin.tie(0);
  4. for(int i = 0 ; i < 10; i++)
  5. {
  6.    cout<<"1 ";
  7. }
  8. int a; cin>>a;
  9. while(1);
复制代码

有点奇怪的是以下代码还是会输出1,即默认缓冲区的情形下,接触绑定没有产生效果。stackoverflow是这样解释的

  1. cin.tie(0);
  2. for(int i = 0 ; i < 10; i++)
  3. {
  4.     cout<<"1 ";
  5. }
  6. int a; cin>>a;
  7. while(1);
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-20 13:33 , Processed in 0.147306 second(s), 32 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表