简体   繁体   中英

How to get correct buffer size with std::istringstream for data parsing

I am sending the message of variable size over zeromq TCP socket. In the examples http://zguide.zeromq.org/cpp:wuclient it was proposed to use std::istringstream to parse the data. The problem is, that it is not accounted for the different buffer size. I end up getting the end of the longer previous message appended to the end of the shorter one.

The simple std::string(static_cast<char*>(request.data()), request.size()); works fine to get the whole message, but I would like to use std::istringstream , because I am going to pass different data types (primitive data types + std::string as the last variable), so std::istringstream could be a good choice for the message parsing.

So this here will put correctly the whole message into rpl variable

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;

But this will not:

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;

How can I get around with it and tell std::istringstream what is the actual buffer size to get the proper string length?

How about:

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

With a read-and-write stringstream, and its write function, you get full control over how many bytes behind a pointer are written. Then you don't need to use the stringstream constructor to populate the buffer, which implicitly constructs a std::string from your char* , without a length constraint. Unless your data is null-terminated, that's not going to work properly.

(See here for the available features of a stringstream.)

If you are completely limited to a std::istringstream , this has no output functionality so you will have to create that string argument explicitly (using its own length-aware constructor), as Sam has shown. Unfortunately, this will copy your entire buffer one extra time. I find it hard to believe that using a std::istringstream is worth that.

Construct your std::istringstream explicitly using a std::string .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM