質問

どうやら boost::asio::async_read 唯一のオーバーロードとして文字列は好きではありません boost::asio::buffer 作成できるようにします const_bufferそのため、すべてを streambuf に読み込むことにこだわっています。
ここで、streambuf の内容を文字列にコピーしたいのですが、どうやら char* への書き込みのみをサポートしているようです (sgetn())、streambuf を使用して istream を作成し、使用します getline().

過剰なコピーを行わずに、streambufs の内容を含む文字列を作成する他の方法はありますか?

役に立ちましたか?

解決

私はそれが "の過度のコピーの" としてカウントするかどうかわかりませんが、あなたはにstringstreamを使用することができます:

std::ostringstream ss;
ss << someStreamBuf;
std::string s = ss.str();

のように、文字列に標準入力からすべてを読むために、行う

std::ostringstream ss;
ss << std::cin.rdbuf();
std::string s = ss.str();

また、あなたはまた、istreambuf_iteratorを使用することができます。あなたはこのまたは上記の方法が高速であるかどうかを測定する必要があります - 私は知りません。

std::string s((istreambuf_iterator<char>(someStreamBuf)), 
               istreambuf_iterator<char>());
上記someStreamBuf

streambuf*を表すので、必要に応じてそのアドレスを取ることを意味します。それは、文字列を返す関数の宣言としてそれを解釈してイテレータと他の関数ポインタ(「最も厄介なパース」)を服用しないように。また、最後の例では、最初の引数の周りに追加の括弧に注意します。

他のヒント

それだの本当にの埋葬<のhref = "http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/overview/core/buffers.html" のrel =ドキュメントの "nofollowをさnoreferrer"> の...

boost::asio::streambuf b ...

を考えるとsize_t buf_size

boost::asio::streambuf::const_buffers_type bufs = b.data();
std::string str(boost::asio::buffers_begin(bufs),
                boost::asio::buffers_begin(bufs) + buf_size);

別の可能性 boost::asio::streambuf 使うことです boost::asio::buffer_cast<const char*>() と組み合わせて boost::asio::streambuf::data() そして boost::asio::streambuf::consume() このような:

const char* header=boost::asio::buffer_cast<const char*>(readbuffer.data());
//Do stuff with header, maybe construct a std::string with std::string(header,header+length)
readbuffer.consume(length);

これは通常の streambuf では機能せず、汚いと思われるかもしれませんが、これが最も速い方法のようです。

boost::asio::streambufのためには、このような解決策を見つけることができます

    boost::asio::streambuf buf;
    /*put data into buf*/

    std::istream is(&buf);
    std::string line;
    std::getline(is, line);

の文字列をプリントアウトします:

    std::cout << line << std::endl;

あなたはここで見つけることがあります。のhttp:// WWW。 boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference/async_read_until/overload3.htmlする

1つはまたasio::streambuf使用してstd::basic_streambuf::sgetnから文字を取得することができます:

asio::streambuf in;
// ...
char cbuf[in.size()+1]; int rc = in.sgetn (cbuf, sizeof cbuf); cbuf[rc] = 0;
std::string str (cbuf, rc);
std ::文字列が明示的にその契約に直接ポインタベースの書き込みをサポートしていないため、

あなただけのstd ::文字列からconst_bufferを作成できる理由があります。あなたはその後、c_str(からconst性const_castを、特定のサイズにあなたの文字列のサイズを変更するような何か悪を行う)と、生のchar *バッファのように扱うが、それは非常にいたずらだといつかトラブルにあなたを取得します可能性があります。

限り、ベクターのサイズを変更しない(あるいはあなたがリサイズに対処するように注意している)として、あなただけの罰金直接ポインタの書き込みを行うことができますので、

私は自分のバッファのためのstd ::ベクトルを使用しています。私がのstd ::文字列としてデータの一部を必要とする場合、私はそれをコピーする必要がありますが、読み込みコールバックを超えて続くことが必要である私は私のリードバッファに対処する方法、何も関わらず、アウトコピーする必要があります。

シンプルな答えはstd::stringにそれを変換し、操作することだろうか。このようなこといくつかの

 std::string buffer_to_string(const boost::asio::streambuf &buffer)
 {
  using boost::asio::buffers_begin;
  auto bufs = buffer.data();
  std::string result(buffers_begin(bufs), buffers_begin(bufs) + buffer.size());
 return result;
}

タスクのための非常に簡潔なコードを与えるます。

私はそれがより多くのようだと思います:


streambuf.commit( number_of_bytes_read );

istream istr( &streambuf );
string s;
istr >> s;

私はbasic_streambufコードに見ていないが、私はそれを文字列に一つだけのコピーであるべきと考えています。

私が最初に答えをテストし、「G ++ -std = C ++ 11」を使用してコンパイルするとき、コンパイラのエラーを得ました どのような私のために働いていたことだった。

        #include <string>
        #include <boost/asio.hpp>
        #include <sstream>           
        //other code ...
        boost::asio::streambuf response;
        //more code
        std::ostringstream sline;
        sline << &response; //need '&' or you a compiler error
        std::string line = sline.str(); 

これは、コンパイルして実行しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top