リダイレクトstd::coutカスタムライター
-
22-08-2019 - |
質問
使いたいこのスニペットから 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 docs がうまく理解の最良の方法ではないかと思います。している方法テキストが表示され、どんな話でデータのostringstream.
何が最も簡単な/のように何も送られstd::目詰まりにリダイレクト方法を選んだ?ので、記入してくださです。eof部など)があり、その過負荷一部のコミット'オペレーターのどこかにその通話は私の方法は?私loking早く簡単に思いを定義シンクなどの力iostreamsは第というものになると私た。
解決
私は Boost.IOStreams
を見ることをお勧めA>。素敵なあなたのユースケースに合わせているようだ、とそれを使用すると、驚くほど簡単です。
#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;
}
他のヒント
私は のだと思いますが、それは空ではありませんしながらの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::coutは、std::cerrから第三者の図書館でログインを利用してlog4cxx、保のします。<br></p><
こういう言葉を思いつきました。って、率直なもの:
私の古いバッファのostream(std::cout)を自分のクラスで取得しますへのアクセスありがとうを書いています。
また新規作成しstd::ostreamオブジェクトのバッファができるよう継続の出力マイコンソールも送信でlogger.めましょう。
コード:
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は常に設定されています。
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;
}
あなただけのSTR()メンバを使用し、その後、ostringstreamの内容を取得したい場合。たとえばます:
string s = oss.str();