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

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

我正在通过 zeromq 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 获得正确字符串长度的实际缓冲区大小是多少?

使用 std::string.

显式构建您的 std::istringstream
std::istringstream iss{std::string{
    static_cast<char*>(request.data()), request.size())
}};

怎么样:

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

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

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

如果你完全局限于std::istringstream,它没有输出功能,所以你必须明确地创建那个string参数(使用它自己的长度感知构造函数),如 Sam 所示。不幸的是,这会额外复制一次整个缓冲区。我发现很难相信使用 std::istringstream 是值得的。