Copy a streambuf's contents to a string

前端 未结 10 1972
时光取名叫无心
时光取名叫无心 2020-11-29 22:19

Apparently boost::asio::async_read doesn\'t like strings, as the only overload of boost::asio::buffer allows me to create const_buffer

相关标签:
10条回答
  • 2020-11-29 22:47

    I tested the first answer and got a compiler error when compiling using "g++ -std=c++11" What worked for me was:

            #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(); 
    

    This compiled and ran.

    0 讨论(0)
  • 2020-11-29 22:49

    I don't know whether it counts as "excessive copying", but you can use a stringstream:

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

    Like, to read everything from stdin into a string, do

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

    Alternatively, you may also use a istreambuf_iterator. You will have to measure whether this or the above way is faster - i don't know.

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

    Note that someStreamBuf above is meant to represent a streambuf*, so take its address as appropriate. Also note the additional parentheses around the first argument in the last example, so that it doesn't interpret it as a function declaration returning a string and taking an iterator and another function pointer ("most vexing parse").

    0 讨论(0)
  • 2020-11-29 22:56

    I mostly don't like answers that say "You don't want X, you want Y instead and here's how to do Y" but in this instance I'm pretty sure I know what tstenner wanted.

    In Boost 1.66, the dynamic string buffer type was added so async_read can directly resize and write to a string buffer.

    0 讨论(0)
  • 2020-11-29 23:03

    One can also obtain the characters from asio::streambuf using 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);
    
    0 讨论(0)
  • 2020-11-29 23:04

    The reason you can only create const_buffer from std::string is because std::string explicitly doesn't support direct pointer-based writing in its contract. You could do something evil like resize your string to a certain size, then const_cast the constness from c_str() and treat it like a raw char* buffer, but that's very naughty and will get you in trouble someday.

    I use std::vector for my buffers because as long as the vector doesn't resize (or you are careful to deal with resizing), you can do direct pointer writing just fine. If I need some of the data as a std::string, I have to copy it out, but the way I deal with my read buffers, anything that needs to last beyond the read callback needs to be copied out regardless.

    0 讨论(0)
  • 2020-11-29 23:09

    For boost::asio::streambuf you may find a solution like this:

        boost::asio::streambuf buf;
        /*put data into buf*/
    
        std::istream is(&buf);
        std::string line;
        std::getline(is, line);
    

    Print out the string :

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

    You may find here: http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference/async_read_until/overload3.html

    0 讨论(0)
提交回复
热议问题