【C++】继承streambuf,对cout进行重定向

又来水了




简单说明

先形容一下要实现的功能:

使用cout语句,但输出在别的地方(可能是文件,可能是管道,也可能是其他奇奇怪怪的东西)

实现上面的功能意味着要想办法控制cout缓冲区清空时的操作,毕竟我还是挺想要cout<<endl或者cout<<flush自带的缓冲区刷新功能的,而这功能让我摸了老半天,(不知道我说的啥的话可以看看下面的【运行结果】),摸完之后爽玩几天的兰斯10然后才开始搞正事。

难点不多,所以很水。




关键词:

cout.rdbuf:这函数将cout重定向到其他的字节流
streambuf::sync:cout.flush()最终会调用到的函数(cout<<endl也会触发/调用cout.flush())。这是我翻源码èn是给找到的…




图文说明:




代码:

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

//继承streambuf:https://www.cnblogs.com/wangshaowei/p/11905831.html
class XJ_Streambuf :public streambuf {
    
    
private:
	enum {
    
     __size = 10 };//缓冲区大小,一般建议设置1024,毕竟1024字节也就1MB大小,内存不痛不痒
	char __buffer[__size + 1] = {
    
     0 };//缓冲区
public:
	XJ_Streambuf() {
    
    
		setbuf(__buffer, __size);
	}

protected://以下全是streambuf类的virtual函数的重写
	int_type overflow(int_type c)override {
    
    //缓冲区溢出时要调用sync清空缓冲区
		printf("/");
		sync();//清空缓冲区
		sputn((char*)&c, 1);//把溢出的字符c塞回到缓冲区
		return c;
	}
	int __CLR_OR_THIS_CALL sync()override {
    
    //这个是关键,在刷新缓冲区时将被被动调用,表现为输出缓冲区内容+清空缓冲区
		printf(__buffer);
		setbuf(__buffer, __size);
		printf(".");
		return 0;
	}
	streambuf* setbuf(char* s, streamsize n)override {
    
    //重置缓冲区
		memset(s, 0, __size);
		setp(s, s, s + n);
		setg(s, s, s + n);
		return this;
	}
};

int main() {
    
    
	char str_P[32] = {
    
     0 };//搞份字符串
	char str_Q[32] = {
    
     0 };
	memset(str_P, 'P', 15);
	memset(str_Q, 'Q', 20);

	XJ_Streambuf buf;//字符缓冲区
	cout.rdbuf(&buf);//cout重定向
	cout << str_P << str_Q << endl;
	return 0;
}




参考内容

cout重定向:https://blog.csdn.net/qq_34039018/article/details/120136038
streambuf继承:https://www.cnblogs.com/wangshaowei/p/11905831.html


其他链接

CSDN(本博客发布于CSDN,附上这条链接是防盗):https://blog.csdn.net/weixin_44733774/article/details/127201133
github(都贴源码了就没必要翻去看github了吧…):https://github.com/Ls-Jan/CPP_streambuf

猜你喜欢

转载自blog.csdn.net/weixin_44733774/article/details/127201133