在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
获取A的流缓冲区并将其存储在某处
将A的流缓冲区设置为B的流缓冲区
如果需要,将A的流缓冲区重置为其先前的流缓冲区
我们执行重定向操作使用ios::rdbuf()方法。对于这个方法,如果不传参数,那么直接返回流对象的buffer指针。如果传递了某个流对象的buffer指针,那么将当前的流对象绑定到那个传递过来的流对象的buffer上。
我们可以使用函数 ios::rdbuf()来执行两次操作。
1) stream_object.rdbuf(): 返回流对象buffer
2) stream_object.rdbuf(streambuf * p): 绑定流对象buffer
下面是一个演示步骤的示例程序
// Cpp程序将cout重定向到文件
#include
#include
#include 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,本文就这样,有什么不对的地方请指正。
来源:https://www.linuxmi.com/io-redirection-c.html