关于C++流的缓冲区的讨论

来源:互联网 发布:ug8.0编程手机教程 编辑:程序博客网 时间:2024/05/19 03:29

现在来讨论一下关于C++的输入输出流的缓冲区问题


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

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

  • endl
  • flush
  • ends
  • unitbuf
  • nounitbuf 

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

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

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

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

ends // ends 则在输入后加上一个空字符,然后再刷新缓冲区

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

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

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

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 刷新缓冲区 没有换行 文本就显示一行


enls

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的指针,将自己管理啊难道次ostream,即,stream.tie(&stream) 将流关联到另一个输出流stream。


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

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


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


这样就取消关联了


最后再总结一下缓冲区

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

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

2.计算机中的缓冲区

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

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

缓冲区(buffer)这个中文译意院子当计算机的高速部件与低速不见通讯时,必须将告诉不见的输出暂存到某处,以保证高速部件与低速部件相吻合,后来这个意思被扩展了,称为“临时存贮区”的意思。

缓冲区就是一块内存区,它用在输入输出设备和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操作。

上面有些是照搬 不要介意,好了,现在就到这里,之后看 在做修改

有什么问题的请及时联系我哦!

原创粉丝点击