endl、flush、ends、unitbuf、nounitbuf区别及详解

一般 C++ 我们使用输出流cout都会用到endl这个操纵符。是吧

C++里有几个可以来控制缓冲区刷新的操纵符。

  • endl
  • flush
  • ends
  • unitbuf
  • nounitbuf 

这几个操纵符是用来控制输出流的缓冲区,这里主要要讲一下这几个的作用。

先来介绍一下这几个的作用:

endl  // endl是用来 完成换行并刷新缓冲区的

flush  // flush是用来 直接刷新缓冲区的

cout << unitbuf// 这里unitbuf 不执行任何动作,而是设置这个cout输出流 在接下来的每次操作之后都进行刷新缓冲区

cout << nounitbuf// 这里nounitbuf则是让cout 回到正常的缓冲方式

ends:

C++STL官方对std::ends的解释是:“此操纵符典型地为 std::ostrstream 在关联输出缓冲区需要为空终止,以作为 C 字符串处理时使用。 不同于 std::endl ,此操纵符不冲入流。”也就是说ends不会立马刷新缓冲区,其作用是输出一个字符串 和一个空字符

介绍完了我们个个来试一下:

cout << "hhhh" << endl; //输出一个字符串 然后 再换行 刷新缓冲区  
cout << "hhhh" << flush; //输出一个字符串 然后 直接刷新缓冲区  
cout << "hhhh" << ends; //输出一个字符串 和一个空字符 不会立马刷新缓冲区  
cout << unitbuf; // 这样的话 设置 cout 接下来的操作都进行一次刷新缓冲区  
cout << "hhh";  // 这里会刷新缓冲区  
cout << nounitbuf; //这里则让cout回到正常的缓冲方式 

这样都执行完了 ,都会在控制台上输出,单是这样输出 大家应该没有什么感受把 都是直接再控制台输出 都会出现字符串

下面我们用 文件流 来演示的刷新缓冲区的作用

ifstream 文件输入流类型

ofstream 文件输出流类型

这里我们用到ofstream 类型来创建一个文件流对象。

下面正式演示各个操纵符的作用来刷新缓冲区:

#include <fstream>  
#include <iostream>  
#include <string>  
using namespace std;  
  
int main()  
{  
    ofstream out_file("test.txt", ofstream::trunc); //这里创建一个文件用来输出写入,以trunc的方式打开,每次打开都会清空文件里的数据  
  
    for (size_t i = 0; i != 5; ++i)  
    {  
        string t;  
        cin >> t;  
        out_file << t; //这里并没有设置什么操纵符来刷新缓冲区  
    }  
  
    return 0;  
}  

下面是我们试着来输入字符串,然后写入到文件流里。我们输入一个字符串 并回车 再看看文本里的数据

我们输入一个字符串 并回车 再看看文本里的数据

 程序并没有真正的写入到文件里,下面我们用到操纵符来看

#include <fstream>  
#include <iostream>  
#include <string>  
using namespace std;  
  
int main()  
{  
    ofstream out_file("test.txt", ofstream::trunc); //这里创建一个文件用来输出写入,以trunc的方式打开,每次打开都会清空文件里的数据  
      
    for (int i = 0; i != 5; ++i)  
    {  
        string t;  
        cin >> t;  
        out_file << t << endl; //这里用到endl 换行并且刷新存入缓冲区里的数据 真正的写入  
    }  
  
    return 0;  
}  

用到endl 下面来运行程序

输入两个字符串 ,然后看看文本

 也已经真正的写入到文件里了,字符串写入然后并且换行,这里就是刷新缓冲区的数据真正写入到文本里来。

这里就已经说明如果没有刷新缓冲区的话,数据是一直再缓冲区里的,而要利用操纵符来刷新缓冲区,真正的写入到文件里

下面还有其他的 直接贴上图片!让大家看下

flush

out_file << t << flush;  

flush 刷新缓冲区 没有换行 文本就显示一行

ends

out_file << t << ends;  

ends 的输出再加上空字符也就是 一个空格 ,但不是立马输出的。

然后是 unitbuf :

out_file << unitbuf; //这里先把cout设置成 接下来 每次输出的进行刷新缓冲区  
 //然后再在相同的程序里 输入5 次  
for (int i = 0; i != 5; ++i)  
{  
    string t;  
    cin >> t;  
    out_file << t;  
}  

是可以的,先设置缓冲方式,然后接下来都会刷新缓冲区,文本排成一行。

nounitbuf

out_file << nounitbuf; //回到正常的缓冲方式,也就是不立即清空缓冲区  

 以上,就讲解完了

下面来说一下  关联输入和输出流

C++ 标准库  提供可以把 一个istream 对象 关联到一个 ostream, 也可以把 一个ostream 关联到 另一个 ostream

提供了一个 成员函数 stream.tie

标准库把cin和cout关联在一起,关联 也就是 当一个输入流被关联到一个输出流时,任何 从输入等待 的读取数据时,都会先刷新被关联的那个 输出流。

tie 有两个重载的版本,一个版本不带参数,返回指向输出流的指针。如果本对象当前关联到一个输出流,则返回的就是指向这个流的指针,如果对象未关联到流,则返回空指针

tie的第二个版本接受一个指向ostream的指针,即,stream.tie(&stream) 将流关联到另一个输出流stream。

cin.tie(&cout);    //这样也就关联在一起  

每次cin读取数据的时候,就会刷新cout的缓冲区。 

cin.tie(nullptr);    //不关联任何流 

这样就取消关联了

最后再总结一下缓冲区

1.什么是缓冲区
缓冲区又称缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些储存空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。

缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

2.计算机中的缓冲区

缓冲器为暂时置放输出或输入资料的内存。

缓冲期内资料自储存设备(如硬盘)来,放置在缓冲器中,待机送至cpu或其他运算设备。

缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速CPU能够协调工作,避免低速输入输出设备占用CPU,解放出CPU,使其能够高效率工作。


3.缓冲区的类型


缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。

1)全缓冲
在这种请款下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲代表是对磁盘文件读写。
2)行缓冲
在这种情况下,当在输入和输出遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表时键盘输入数据。
3)不带缓冲
也就是不带行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。
4.缓冲区地刷新
下列情况会引发缓冲区地刷新:
缓冲区满;
执行flush语句;
执行endl语句;
关闭文件;
可见,缓冲区满或关闭文件时都会刷新缓冲区,进行真正地I/O操作。
C++中,我们可以使用flush函数来刷新缓冲区(执行I/O操作并清空缓冲区)
windows 系统 的 的全缓冲区的大小是4096个字节,也就是输入到4096字节就不能再输入了
清空缓冲区。
在缓冲区满了之后,缓冲区会刷新缓冲区,执行真正的I/O操作。
cerr << "error" ; 这样则是无缓冲 立即执行I/O操作。
 

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值