Как получить правильный размер буфера с std :: istringstream для разбора данных - PullRequest
0 голосов
/ 14 января 2019

Я отправляю сообщение переменного размера через TCP-сокет zeromq. В примерах http://zguide.zeromq.org/cpp:wuclient было предложено использовать std::istringstream для анализа данных. Проблема в том, что он не учитывает другой размер буфера. Я заканчиваю тем, что получаю конец более длинного предыдущего сообщения, добавляемый в конец более короткого.

Простой std::string(static_cast<char*>(request.data()), request.size()); прекрасно работает для получения всего сообщения, но я хотел бы использовать std::istringstream, потому что я собираюсь передавать различные типы данных (примитивные типы данных + std :: string в качестве последней переменной), так что std::istringstream может быть хорошим выбором для разбора сообщения.

Так что здесь все правильно будет помещено в переменную rpl

zmq::message_t request;
//  Wait for next request from client
socket_.recv (&request);
auto rpl = std::string(static_cast<char*>(request.data()), request.size());
std::cout << rpl << std::endl;

Но это не будет:

zmq::message_t request;
//  Wait for next request from client
socket_.recv (&request);
std::istringstream iss(static_cast<char*>(request.data()));
std::string rpl;
iss >> rpl;
std::cout << rpl << std::endl;

Как мне обойти это и сказать std::istringstream каков фактический размер буфера, чтобы получить правильную длину строки?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Как насчет:

std::stringstream iss;
iss.write(static_cast<char*>(request.data()), request.size());

С помощью потока строк с возможностью чтения и записи и его функцией write вы получаете полный контроль над количеством записываемых байтов за указателем. Тогда вам не нужно , чтобы использовать конструктор stringstream для заполнения буфера, который неявно создает std::string из вашего char* без ограничения длины. Если ваши данные не заканчиваются нулем, это не будет работать должным образом.

(См. здесь , чтобы узнать о доступных функциях струнного потока.)

Если вы полностью ограничены std::istringstream, это не имеет никакой выходной функциональности, поэтому вам придется явно создать этот аргумент string (используя собственный конструктор с учетом длины), как Сэм показано на рисунке. К сожалению, это скопирует весь ваш буфер еще один раз. Мне трудно поверить, что использование std::istringstream того стоит.

0 голосов
/ 14 января 2019

Создайте свой std::istringstream явно, используя std::string.

std::istringstream iss{std::string{
    static_cast<char*>(request.data()), request.size())
}};
...