在C语言中,我们可以使用函数freopen()将现有文件指针重定向到另一个流。freopen()的原型如下

FILE * freopen ( const char * filename, const char * mode, FILE * stream );

例如,要将stdout重定向为文本文件,我们可以编写

freopen (“text_file.txt”, “w”, stdout);

虽然在C++中仍然支持这种方法,但本文将讨论另一种重定向 I/O streams的方法。

C++作为一种面向对象的编程语言,不仅使我们能够定义自己的流,而且还可以重定向标准流。因此,在C++中,流是一个对象,其行为由类定义。因此,任何表现得像流的东西都是流。

C++中的流对象主要有三种类型:

  • istream : 此类型的流对象只能从流执行输入操作
  • ostream : 这些对象只能用于输出操作。
  • iostream : 可以同时用于输入和输出操作

顾名思义

i代表输入input

o代表输出output

stream//流

iostream//输入输出流,这只是C++的一个流文件,因为C++的输入输出都是流处理的

istream//就是只管输入的流

ostream//就是只管输出的流

(理论上应该是iostream包含了istream和ostream。但是如果只想使用ostream中的某个功能却使用了这个iostream,而iostream比较大,又包含了istream,那么这样的调用会浪费资源)

所有这些类以及文件流类都派生自以下类:ios和streambuf。因此,filestream和IO流对象的行为类似。

所有流对象还具有类streambuf的关联数据成员。简单地说,streambuf对象是流的缓冲区。从流中读取数据时,我们不会直接从源中读取数据,而是从链接到源的缓冲区中读取数据。同样,首先在缓冲区上执行输出操作,然后在需要时刷新缓冲区(将其写入物理设备)。

C++允许我们为任何流设置流缓冲区。因此,重定向流的任务只不过是更改与流相关联的流缓冲区。因此,我们需要将流A重定向到流B

  1. 获取A的流缓冲区并将其存储在某处
  2. 将A的流缓冲区设置为B的流缓冲区
  3. 如果需要,将A的流缓冲区重置为其先前的流缓冲区

我们执行重定向操作使用ios::rdbuf()方法。对于这个方法,如果不传参数,那么直接返回流对象的buffer指针。如果传递了某个流对象的buffer指针,那么将当前的流对象绑定到那个传递过来的流对象的buffer上。

我们可以使用函数 ios::rdbuf()来执行两次操作。

1) stream_object.rdbuf(): 返回流对象buffer
2) stream_object.rdbuf(streambuf * p): 绑定流对象buffer

下面是一个演示步骤的示例程序

// Cpp程序将cout重定向到文件 
#include <fstream> 
#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 
    fstream file; 
    file.open("cout.txt", ios::out); 
    string line; 

    // cout的备份流缓冲区
    streambuf* stream_buffer_cout = cout.rdbuf(); 
    streambuf* stream_buffer_cin = cin.rdbuf(); 

    // 获取文件的streambuffer 
    streambuf* stream_buffer_file = file.rdbuf(); 

    // 将cout重定向到文件
    cout.rdbuf(stream_buffer_file); 

    cout << "Linux迷www.linuxmi.com这行写入文件" << endl; 

    // 将cout重定向回屏幕
    cout.rdbuf(stream_buffer_cout); 
    cout << "www.linuxmi.com这一行被写入屏幕" << endl; 

    file.close(); 
    return 0; 
}

屏幕输出:

www.linuxmi.com这一行被写入屏幕

下面这一行将写入文件
Linux迷www.linuxmi.com这行写入文件

注意:

以上步骤可以压缩为一个步骤

auto cout_buf = cout.rdbuf(file.rdbuf())

// 设置流缓冲区和返回先前的
streambuffer back to cout_buf

OK,本文就这样,有什么不对的地方请指正。

发表评论