Doubling a stream

Doubling a stream

本文关键字:stream Doubling      更新时间:2023-10-16

我使用cerr流作为错误输出,但我也想将这些错误输出保存在内存中的stringstream中。

I'm looking to turn this:

stringstream errorString;
cerr << " Something went wrong ";
errorString << " Something went wrong ";

myErr << " Something went wrong ";

其中myErr是一个类的实例,它将这个值存储在stringstream中,并输出给cerr。

谢谢你的帮助

您可以像这样创建myErr类的类型:

class stream_fork
{
    std::ostream& _a;
    std::ostream& _b;
public:
    stream_fork( std::ostream& a, std::ostream& b)
        :   _a( a ),
            _b( b )
    {
    }
    template<typename T>
    stream_fork& operator<<( const T& obj )
    {
        _a << obj;
        _b << obj;
        return *this;
    }
    // This lets std::endl work, too!
    stream_fork& operator<<( std::ostream& manip_func( std::ostream& ) )
    {
        _a << manip_func;
        _b << manip_func;
        return *this;
    }
};

用法:

stream_fork myErr( std::cerr, errorString );
myErr << "Error Message" << std::endl;

你可以使用Boost.IOStreams.

#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <iostream>
#include <sstream>
namespace io = boost::iostreams;
int main() {
    std::stringstream ss;
    io::tee_device<decltype(ss), decltype(std::cerr)> sink(ss, std::cerr);
    io::stream<decltype(sink)> stream(sink);
    stream << "foo" << std::endl;
    std::cout << ss.str().length() << std::endl;
    return 0;
}

MyErr类中覆盖operator<<

MyErr& operator<< ( MyErr& myErr, std::string message)
{
    cerr << message;
    errorString << message; //Where errorString is a member of the MyErr class
    return myErr;
}

在你想记录错误的地方:

int main()
{
    MyErr myErr;
    myErr << " Something went wrong. ";
    return 0;
}

你可能想让MyErr一个单例类,这样所有写到errorString的东西都在一个地方。

使用Boost tee

您需要子类streambuf并将myErr声明为使用您的子类的ostream。让输入函数什么都不做,然后让输出函数复制到你需要的任何流中。

12年前我有一个班级做过类似的事情,但我已经忘记了。我没能找到一个很好的例子,但是streambuf的文档可以作为一个起点。注意保护的输出功能