将streambuf的内容复制到字符串

tst*_*ner 33 c++ string boost streambuf boost-asio

显然boost::asio::async_read不喜欢字符串,因为唯一的重载boost::asio::buffer允许我创建const_buffers,所以我坚持将所有内容都读成streambuf.
现在我想将streambuf的内容复制到一个字符串中,但它显然只支持写入char*(sgetn()),使用streambuf创建一个istream并使用getline().

有没有其他方法可以创建一个带有streambufs内容的字符串,而无需过多的复制?

Joh*_*itb 46

我不知道它是否算作" 过度复制 ",但您可以使用字符串流:

std::ostringstream ss;
ss << someStreamBuf;
std::string s = ss.str();
Run Code Online (Sandbox Code Playgroud)

就像,从stdin到字符串读取所有东西,做

std::ostringstream ss;
ss << std::cin.rdbuf();
std::string s = ss.str();
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用istreambuf_iterator.您将不得不衡量这种或上述方式是否更快 - 我不知道.

std::string s((istreambuf_iterator<char>(someStreamBuf)), 
               istreambuf_iterator<char>());
Run Code Online (Sandbox Code Playgroud)

请注意,someStreamBuf上面的意思是表示a streambuf*,因此请适当地使用其地址.还要注意最后一个示例中第一个参数周围的附加括号,这样它就不会将它解释为返回字符串并获取迭代器和另一个函数指针的函数声明("最令人烦恼的解析").

  • 谢谢,istreambuf_iterator是我一直在寻找的. (2认同)

Sea*_*ris 38

真的埋没在文档中 ......

鉴于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);
Run Code Online (Sandbox Code Playgroud)

  • 这很好用!如果你想将整个东西放入字符串中,你可以使用`b.size()`而不是`buf_size`. (3认同)

tst*_*ner 24

另一种可能性boost::asio::streambufboost::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);
Run Code Online (Sandbox Code Playgroud)

这不适用于普通的streambuf,可能会被认为是脏的,但它似乎是最快的方式.

  • 正如人们现在看到的那样,只有当你的流有一个分配和填充的单个缓冲区对象时,这才会起作用.如果流有多个缓冲区,则以这种方式拧紧.你需要做什么以及你应该做些什么以保证工作是获得缓冲区的迭代器,然后转换迭代器.您可以通过访问buffer-> data().begin()来获取这些迭代器. (2认同)

ier*_*hou 13

因为boost::asio::streambuf你可以找到这样的解决方案:

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

    std::istream is(&buf);
    std::string line;
    std::getline(is, line);
Run Code Online (Sandbox Code Playgroud)

打印出字符串:

    std::cout << line << std::endl;
Run Code Online (Sandbox Code Playgroud)

您可以在这里找到:http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference/async_read_until/overload3.html


tst*_*ner 0

我最不喜欢这样的答案:“你不想要 X,你想要 Y,这里是如何做 Y”,但在这种情况下,我很确定我知道 tstenner 想要什么。

在Boost 1.66中,添加了动态字符串缓冲区async_read类型,因此可以直接调整大小并写入字符串缓冲区。