如何使用std :: istringstream获取正确的缓冲区大小以进行数据解析

时间:2019-01-14 11:44:06

标签: c++ parsing zeromq

我正在通过0mq TCP套接字发送可变大小的消息。在示例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 :(得分:1)

怎么样:

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

使用读写字符串流及其write函数,您可以完全控制指针后面写入了多少字节。然后,您不需要使用stringstream构造函数来填充缓冲区,该缓冲区从您的std::string隐式构造一个char*,而没有长度限制。除非您的数据以null终止,否则它将无法正常工作。

(有关字符串流的可用功能,请参见here。)

如果您完全限于std::istringstream,则它没有输出功能,因此您将必须显式创建该string参数(使用其自身的长度感知构造函数) ),如Sam所示。不幸的是,这将额外复制整个缓冲区一次。我很难相信使用std::istringstream是值得的。

答案 1 :(得分:0)

使用std::istringstream显式构造std::string

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