• [转]c++流缓冲---rdbuf()


    C++标准库封装了一个缓冲区类streambuf,以供输入输出流对象使用。每个标准C++输出输出流对象都包含一个指向streambuf的指针,用 户可以通过调用rdbuf()成员函数获得该指针,从而直接访问底层streambuf对象。因此,可以直接对底层缓冲区进行数据读写,从而跳过上层的格 式化输入输出操作。
    对于文件流类和字符串流类,分别派生了相应的流缓冲区类型,参考最后面的代码:
    流对象通过调用rdbuf()获得了底层streambuf对象的指针,也就可以通过该指针调用streambuf支持你各种操作进行输入输出。本文对这些操作不予讨论,在这里主要介绍如何利用该指针实现文件内容的输出。
    输出流提供了一个重载版本operator<<,它以streambuf指针为参数,实现把streambuf对象中的所有字符输出到输出流 出中;输入流也提供了一个对应的operator>>重载版本,把输入流对象中的所有字符输入到streambuf对象中。输入流的get成 员重载版本中还有以streambuf指针为参数的版本,也可以用来把输入流的东西写入到输出流缓冲区中。

    下面用三种方法实现把一个文件的内容输出标准输出(当然还可以通过普通的标准格式化输入输出完成):
    法一:通过operator<<

    #include <iostream> 
    #include <fstream> 
    using namespace std; 
    int main() 
    { 
    ifstream fin("source.dat"); 
    cout<<fin.rdbuf(); //猜测实际上缓存的数据载体就是一个char*,然后重载了<<运算符
    return 0; 
    } 

    法二:利用get成员函数

    ifstream fin("source.dat"); //get里边传入什么参数,就把流的内容输入到什么里边,这是输入流的基本概念
    while (!fin.get(*cout.rdbuf()).eof()) { // extract a line input 
    if (fin.fail()) // blank line 
    fin.clear(); 
    cout<<char(fin.get()); // extract '
    ' 
    }

    代码解释:由于上面代码中的get版本在遇到' '字符时,结束提取,所以需要用循环实现整个文件内容的输出。另外,当此版本get函数遇到空行 时,因为没有提取到任何字符(注意:get不提取回车符),注意会设置失败标志ios::failbit,所以此时应当调用clear()函数清除错误标 志。同样,因为该版本get不会提取回车符,所以需要用另一版本的get()提取回车符。

    法三:利用重载的get函数

    ifstream fin("main.cpp"); 
    fin.get(*cout.rdbuf(), EOF);

    代码解释:这个版本的get成员函数可以自定义提取终止符。这里通过设置为文件结束符(EOF)来达到一下提取整个文件的目的。

    当然,你可以把上面的cout换成任意的输出流,比如文件输出流,从而可以实现文件的拷贝功能。

    另外,上面代码中并没有使用输入流的>>操作符,因为>>和<<是相对的,只是把操作数交换一下位置罢了。因此,你 可以把上面代码中用out<<

  • 相关阅读:
    我业余时间开发的东西文本编辑器 美丽的控件
    讲讲语言转换程序:将一种语言转换为另一种语言的程序
    调整心态,正确应对所学技术的失宠?(至F#,SL的学习者们)
    开贴说说文本编辑器的那些事情捕获输入内容
    开贴说说文本编辑器的那些事情 字符串的宽度
    电话亭。
    【旅行】西湖——初秋。
    偶这个前端设计师有生以来写过的最复杂的程序业务逻辑(菜鸟贴)。
    “页面制作人员”?“页面工程师”?“页面架构师”?滚一边去!
    【旅行】生的活力——西塘正午。
  • 原文地址:https://www.cnblogs.com/gangmiangongjue/p/7296400.html
Copyright © 2020-2023  润新知