我想要使用这种片段 先生-Edd的iostreams的文章 印std::堵塞的地方。

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

int main()
{
    std::ostringstream oss;

    // Make clog use the buffer from oss
    std::streambuf *former_buff =
        std::clog.rdbuf(oss.rdbuf());

    std::clog << "This will appear in oss!" << std::flush;

    std::cout << oss.str() << '\\n';

    // Give clog back its previous buffer
    std::clog.rdbuf(former_buff);

    return 0;
}

因此,在一个mainloop,mainloop,我会做这样的事情

while (! oss.eof())
{
    //add to window text somewhere
}

这里的 ostringstream文档 但我有麻烦了解的最佳方式做到这一点。我有一个方法,显示的案文,我只是想称呼它与任何数据在ostringstream。

什么是最简单/最佳的方式得到任何东西送到std::堵塞重新指向一个方法我选择?它是作为以上,并填写在儿!eof部分(不知道该如何),或者是有更好的方式,说通过重载的一些'承诺'操作员的地方,叫我的方法?我供不同的天快速和容易的,我真的不想开始汇和定义等与提高iostreams为该条不-那东西是我的头。

其他提示

我觉得您想从ostream的拉文虽然它不是空的。你可以做这样的事情:

std::string s = oss.str();
if(!s.empty()) {
    // output s here
    oss.str(""); // set oss to contain the empty string
}

让我知道这是不是你想要的。

当然,更好的解决方法是删除中间人,并有一个新的流缓冲去的地方,你的真的想要的话,没必要以后查询。像这样(注意,这会为每一个字符,但有大量的缓冲的streambuf选项,以及):

class outbuf : public std::streambuf {
public:
    outbuf() {
        // no buffering, overflow on every char
        setp(0, 0);
    }

    virtual int_type overflow(int_type c = traits_type::eof()) {
        // add the char to wherever you want it, for example:
        // DebugConsole.setText(DebugControl.text() + c);
        return c;
    }
};

int main() {
    // set std::cout to use my custom streambuf
    outbuf ob;
    std::streambuf *sb = std::cout.rdbuf(&ob);

    // do some work here

    // make sure to restore the original so we don't get a crash on close!
    std::cout.rdbuf(sb);
    return 0;

}

我需要抓住输出到std::状况和性传播疾病::cerr从第三方图书馆,并记录它们使用log4cxx,并且仍然保留原来的产出。

这是什么,我来了。这是很简单:

  • 我替换旧缓冲区的一个ostream(如性传染病::诉讼)与我自己的类,因此,我访问到什么是书面的。

  • 我还创建了一个新的性传染病::ostream目的与老缓冲区这样我可以继续得到输出我的控制台上,除了发送给我的记录。我找到一种方便。

代码:

class intercept_stream : public std::streambuf{
public:
    intercept_stream(std::ostream& stream, char const* logger):
      _logger(log4cxx::Logger::getLogger(logger)),
      _orgstream(stream),
      _newstream(NULL)
    {
        //Swap the the old buffer in ostream with this buffer.
        _orgbuf=_orgstream.rdbuf(this);
        //Create a new ostream that we set the old buffer in
        boost::scoped_ptr<std::ostream> os(new std::ostream(_orgbuf));
        _newstream.swap(os);
    }
    ~intercept_stream(){
        _orgstream.rdbuf(_orgbuf);//Restore old buffer
    }
protected:
    virtual streamsize xsputn(const char *msg, streamsize count){
        //Output to new stream with old buffer (to e.g. screen [std::cout])
        _newstream->write(msg, count);
        //Output to log4cxx logger
        std::string s(msg,count);
        if (_logger->isInfoEnabled()) {
            _logger->forcedLog(::log4cxx::Level::getInfo(), s, LOG4CXX_LOCATION); 
        }
        return count;
    }
private:
    log4cxx::LoggerPtr _logger;
    std::streambuf*    _orgbuf;
    std::ostream&      _orgstream;
    boost::scoped_ptr<std::ostream>  _newstream;
};

然后使用它:

std::cout << "This will just go to my console"<<std::endl;
intercept_stream* intercepter = new intercept_stream(std::cout, "cout");
std::cout << "This will end up in both console and my log4cxx logfile, yay!" << std::endl;

有关的log4cxx例如,你必须覆盖溢出()和同步()否则接收到的第一数据流之后的badbit总是被设置。

请参阅: http://groups.google.com/group /comp.lang.c++.moderated/browse_thread/thread/fd9d973282e0a402/a872eaedb142debc

InterceptStream::int_type InterceptStream::overflow(int_type c)
{
    if(!traits_type::eq_int_type(c, traits_type::eof()))
    {
        char_type const t = traits_type::to_char_type(c);
        this->xsputn(&t, 1);
    }
    return !traits_type::eof();
}

int InterceptStream::sync()
{
    return 0;
}

如果你只是想获得ostringstream的内容,然后利用它的STR()成员。例如:

string s = oss.str();    
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top