[转]C++流缓冲区的应用——输出文件内容的方法举例

C++流缓冲区的应用——输出文件内容的方法举例 (2007-01-23 16:53)



   本文主要简单讨论C++流对象的底层缓冲区,并举例介绍如何使用该缓冲区进行文件内容的输出。如果文中有错误或遗漏之处,敬请指出,谢谢!
 
   作者: tyc611, 2007-01-23

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

 

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

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    ifstream fin("source.dat");
    cout<<fin.rdbuf();
    
return 0;
}

法二:利用get成员函数

ifstream fin("source.dat");
while (!fin.get(*cout.rdbuf()).eof()) { // extract a line input
    if (fin.fail())        // blank line
        fin.clear();
    cout<<char(fin.get()); // extract '\n'
}

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

法三:利用重载的get函数

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

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

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

   另外,上面代码中并没有使用输入流的>>操作符,因为>>和<<是相对的,只是把操作数交换一下位置罢了。因此,你可以把上面代码中用out<<in.rdbuf()的地方换成in>>out.rdbuf(),代码的功能完全一样,效果也一样。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值