C++输出流重定向

### 背景 C++程序输出的重定向有几种实现方式,若是重定向到文件中的话,在Linux上使用重定向指令(>)即可。但是如果需要再程序中重定向到其他流内的话,有不同的实现方式。 之前在一个C++项目中,最初的提示信息都是cout输出,后来加上Shell之后需要把这些cout的内容收集出来放入共享内存内,如果一个个的改的话,将会是一件很麻烦的事情,幸好C++内的输入输出都用的流的概念,而流是可以重定向的,用到的主要函数是rdbuf(),下面就简单介绍一下内容。

rdbuf使用例子

C++中的rdbuf有两种形式,详细可见reference

  1. get (1) streambuf* rdbuf() const;
  2. set (2) streambuf* rdbuf (streambuf* sb);

第一个是获取当前流对象的streambuf指针,后者设置当前流对象的streambuf指针
举个使用例子,在我的程序中将所有cout的内容收集到stringstream流中:

1
2
3
4
5
stringstream redirect_stream;//cout的重定向流
streambuf * backup = cout.rdbuf();//备份
cout.rdbuf(redirect_stream.rdbuf());//重定向
string output;//输出的内容存放变量
output = redirect_stream.str();//复制到输出

以上就完成了将所有输出收集的功能,很好的体现了流的好处
当然还有其他rdbuf的使用方法,如直接输出文件内容:

1
2
ifstream infile("test.txt");  
cout << infile.rdbuf(); //把infile流对象中的流重定向到标准输出cout上

或者简单的复制文件

1
2
3
4
fstream infile("test.txt", ios::in);
fstream outfile("test.bak.txt", ios::out);
//这里没有判断文件是否存在,仅为方便而省略
outfile<<infile.rdbuf(); //将infile流中的数据传入outfile流中

以及简单的输出重定向到文件:

1
2
3
4
5
6
7
streambuf * backup = cout.rdbuf();//备份
fstream outfile("output.txt", ios::out);
cout.rdbuf(outfile.rdbuf());//重定向
//从这里开始cout<<content输出的内容都会重定向到文件内
cout<<'test'<<endl;//重定向到文件
cout.rdbuf(backup);//重新输出到标准输出(屏幕)
cout<<'test to screen'<<endl;//输出到屏幕

rdbuf对流的一些理解和使用有些帮助,可以留意一下