加倍流

时间:2011-09-07 14:18:37

标签: c++ stream

我正在使用cerr流进行错误输出,但我也希望将这个错误输出保存在内存中的字符串流中。

我想转此:

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

myErr << " Something went wrong ";

其中myErr是一个类的实例,它将其存储在字符串流中并输出到cerr。

感谢您的帮助。

5 个答案:

答案 0 :(得分:3)

您可以像这样创建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;

答案 1 :(得分:2)

您可以使用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;
}

答案 2 :(得分:1)

覆盖operator<<班级中的MyErr

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的所有内容放在一个位置。

答案 3 :(得分:1)

使用Boost tee

答案 4 :(得分:0)

您需要将streambuf子类化,并将myErr声明为使用您的子类的ostream。使输入函数不执行任何操作,然后将输出函数复制到您需要的任何流中。

我有一个班级在12年前做过类似的事情,但已经忘记了它。我无法找到一个好的例子,但docs for streambuf可能是一个起点。专注于受保护的输出功能。