문제

이 스 니펫을 사용하고 싶습니다 Mr-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;
}

그래서 메인 루프에서는 같은 일을 할 것입니다.

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

여기에 있습니다 타조 스트림 문서 그러나 나는 이것을하는 가장 좋은 방법을 이해하는 데 어려움을 겪고 있습니다. 텍스트를 표시하는 메소드가 있으며 Ostringstream의 데이터와 함께 호출하고 싶습니다.

STD :: CLOG로 전송하는 가장 쉬운/가장 좋은 방법은 무엇입니까? 위와 같이, 그리고 while! eof part (어떻게 확실하지 않음), 또는 더 좋은 방법이 있습니까? 나는 빠르고 쉬운 것을 위해 loking 다. 나는 기사와 같이 싱크를 정의하고 싶지 않다.

도움이 되었습니까?

해결책

나는 당신이 보는 것이 좋습니다 Boost.IOStreams. 사용 사례에 잘 맞는 것 같습니다. 사용하는 것은 놀랍게도 간단합니다.

#include <boost/iostreams/concepts.hpp> 
#include <boost/iostreams/stream_buffer.hpp>
#include <iostream>

namespace bio = boost::iostreams;

class MySink : public bio::sink
{
public:
    std::streamsize write(const char* s, std::streamsize n)
    {
        //Do whatever you want with s
        //...
        return n;
    }
};

int main()
{
    bio::stream_buffer<MySink> sb;
    sb.open(MySink());
    std::streambuf * oldbuf = std::clog.rdbuf(&sb);
    std::clog << "hello, world" << std::endl;
    std::clog.rdbuf(oldbuf);
    return 0;
}

다른 팁

생각한다 비어 있지 않은 상태에서 타조에서 텍스트를 당기고 싶습니다. 당신은 다음과 같은 일을 할 수 있습니다 :

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

이것이 당신이 원하는 것이 아닌지 알려주세요.

물론 더 나은 해결책은 중간 맨을 제거하고 새로운 스트림 부프가 어디를 가든지하는 것입니다. 진짜 나중에 조사 할 필요가 없습니다. 이와 같은 것 (참고, 이것은 모든 문자에 대해하지만 StreamBufs에는 많은 버퍼링 옵션이 있습니다) :

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 :: cout 및 std :: cerr에 출력을 가져 와서 log4cxx를 사용하여 로그인하고 원래 출력을 유지해야했습니다.

이것이 제가 생각해 낸 것입니다. 꽤 간단합니다.

  • 나는 타조의 오래된 버퍼 (std :: cout와 같은)를 내 자신의 클래스로 교체하여 그것에 기록 된 내용에 액세스 할 수 있도록합니다.

  • 또한 오래된 버퍼가있는 새 STD :: 타조 객체를 만들어 로거로 보내는 것 외에도 콘솔로 계속 출력을 얻을 수 있습니다. 나는 편리하다고 생각합니다.

암호:

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 예제의 경우 OverFlow () 및 Sync ()를 재정의해야합니다. 그렇지 않으면 첫 번째 스트림이 수신 된 후에는 항상 Badbit이 설정됩니다.

보다:http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/fd973282e0a402/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