c++ 重定向 cout / cerr 到自定义日志方法

Posted Eritque arcus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ 重定向 cout / cerr 到自定义日志方法相关的知识,希望对你有一定的参考价值。

代码:

#include <iostream>
#include <sstream>
#define log(x)
#define err(x)

class OStreamRedirector 
public:
    ~OStreamRedirector() 
        obj.rdbuf(old);
    

    /**
         * @brief 重定向 obj 的流
         * @param obj 需要重定向的流
         * @param new_buffer 重定向到的新缓冲区
         */
    explicit OStreamRedirector(std::ostream &obj, std::streambuf *newBuffer)
        : old(obj.rdbuf(newBuffer)), obj(obj) 

private:
    // 被重定向的流
    std::ostream &obj;
    // 旧的缓冲区目标
    std::streambuf *old;
;

class OString : private std::streambuf, public std::ostream 
public:
    // 输出是否为 info 级别
    explicit OString(bool info) : std::ostream(this), info(info) 

private:
    bool info;
    // 缓冲区
    std::ostringstream result;
    // 加入缓冲区
    int overflow(std::streambuf::int_type c) override 
        if (c == EOF)
            out();
        else
            result.put((std::streambuf::char_type) c);
            return c;
        
        // std::streambuff 的 sync
        int sync() override 
            out();
            return 0;
        
        // 输出缓冲区内容, 相当于 flush
        void out() 
        // 执行log系统输出
            if (info)
                log(result.str());
            else
                err(result.str());
            result.str("");
        
    ;

用法:

OString outTarget(true);
OStreamRedirector outRedirectorstd::cout, outTarget.rdbuf();
OString errTarget(false);
OStreamRedirector errRedirectorstd::cerr, errTarget.rdbuf();

值得注意两个点:

  1. 是在overflow()里面不能判断输入流是否结束, 不会出现传入 c == EOF 的情况
  2. 是 cout 和 cerr 不会自动 flush(), 可能需要调用std::endl或者手动 flush
--EOF--

以上是关于c++ 重定向 cout / cerr 到自定义日志方法的主要内容,如果未能解决你的问题,请参考以下文章

c++ 重定向 cout / cerr 到自定义日志方法

cout、cerr、clog的rdbuf如果改成重定向到文件,是不是需要重新设置?

C++代码调试的学习笔记

会话超时后如何将用户重定向到自定义网页?

C++ 中的标准输出流是线程安全的(cout、cerr、clog)吗?

查看网页中是不是存在字符串后如何重定向到自定义网页