문제

보기에 boost::asio::async_read 유일한 과부하로 문자열을 좋아하지 않습니다 boost::asio::buffer 내가 만들 수있게 해줍니다 const_bufferS, 그래서 나는 모든 것을 스트리트 부프로 읽는 데 붙어 있습니다.
이제 StreamBuf의 내용을 문자열로 복사하고 싶지만 char*에 대한 글쓰기 만 지원합니다.sgetn()), StreamBuf와 함께 istream을 만들고 사용 getline().

과도한 복사없이 StreamBufs 내용으로 문자열을 만들 수있는 다른 방법이 있습니까?

도움이 되었습니까?

해결책

나는 그것이 "로 간주되는지 모르겠다"과도한 복사", 그러나 당신은 stringstream을 사용할 수 있습니다.

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

stdin에서 끈으로 모든 것을 읽으려면

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

또는 a를 사용할 수도 있습니다 istreambuf_iterator. 당신은 이것 또는 위의 길이 더 빠른지를 측정해야 할 것입니다 - 나는 모른다.

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

주목하십시오 someStreamBuf 위의 것은 a를 대표하기위한 것입니다 streambuf*, 주소를 적절하게 가져 가십시오. 또한 마지막 예제에서 첫 번째 인수 주위의 추가 괄호 안에서 문자열을 반환하고 반복자와 다른 함수 포인터 ( "대부분의 vexing parse")를 취하는 함수 선언으로 해석하지 않도록하십시오.

다른 팁

이것의 진짜 매장 문서에서...

주어진 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);

이것은 정상적인 스트림 부프와 함께 작동하지 않으며 더러워진 것으로 간주 될 수 있지만 가장 빠른 방법 인 것 같습니다.

을 위한 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

문자도 얻을 수도 있습니다 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 :: string에서 const_buffer 만 만들 수있는 이유는 std :: string이 계약에서 직접 포인터 기반 쓰기를 명시 적으로 지원하지 않기 때문입니다. 당신은 당신의 줄을 특정 크기로 크기를 조정 한 다음 const_cast를 c_str ()에서 const_cast와 같은 사악한 일을 할 수 있고 그것을 생 차* 버퍼처럼 취급 할 수 있지만, 그것은 매우 장난스럽고 언젠가 당신을 곤경에 빠뜨릴 것입니다.

벡터가 크기를 조정하지 않는 한 (또는 크기 조정에주의를 기울이지 않으면) 직접 포인터를 잘 작성할 수 있기 때문에 버퍼에 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