【问题标题】:How to assign Google protocol buffer SerializeAsString() output which contains embedded nulls to std::string?如何将包含嵌入式空值的 Google 协议缓冲区 SerializeAsString() 输出分配给 std::string?
【发布时间】:2015-05-21 09:47:00
【问题描述】:

我正在尝试使用 google 协议缓冲区将消息序列化为 C++ 中的字符串,并将序列化结果(其中包含嵌入的空值)分配给 std::string。以下是我的代码:

std::string result = message.SerializeAsString();

忽略第一个 \0 字符之后的字符。结果没有完整的序列化字符串。我尝试了以下明确指定长度的方法。

int size = message.ByteSize();
std::string result(std::string(message.SerializeAsString()), size);

它也不适合我。有没有其他方法可以做到这一点?

提前致谢。

【问题讨论】:

  • cout << result.length(); 会报告什么?
  • 这些字符可能不会在string 中被忽略,而是在您用来检查它们的工具中。
  • @RichardHodges 结果的长度为 430。序列化字符串在其第 15 个索引中具有第一个空字符。

标签: c++ serialization null protocol-buffers stdstring


【解决方案1】:

在 std::strings 中存储 NUL 字节没有问题。您可以正常分配字符串。您的两个代码 sn-ps 都应该可以正常工作。

如果您调用.c_str() 并尝试将字符串传递给期望const char* 的东西,就会出现问题。此时,const char* 的接收者不知道字符串的大小,因此假定它在第一个 NUL 字节处结束。所以,不要那样做 - 始终确保您要么传递 std::string 整体,要么传递指针和大小(来自 .size())。

您评论了需要转换为std::wstring 的另一个答案。编辑:我把我的 cmets 移到了你的other question

【讨论】:

  • "你的两个代码 sn-ps 应该都能正常工作。"实际上,问的 sn-p OP 有问题。他正在使用构造函数的 string(const char*) 版本创建字符串的中间副本。我在回答中提到了这一点。
  • 是的。问题出在 std::wstring 上。我使用了 const char* 而不是将序列化字符串转换为 std::wstring。 “始终确保您要么传递整个 std::string,要么传递指针和大小(来自 .size())。” - 它对我有用。非常感谢:)
  • @bashrc 我看不到 OP 在哪里调用string(const char*)SerializeAsString() 返回 std::string,而不是 const char*
【解决方案2】:
std::string result(message.SerializeAsString(), size);

当你创建临时字符串时

std::string(message.SerializeAsString())

这部分消耗嵌入的空值。

【讨论】:

  • 非常感谢。 std::string result = std::string(wordseq.SerializeAsString()) 对我有用。现在我需要将此字符串复制到 std::wstring。它也是一个空终止的字符串吗?我试过 std::wstring finalresult(result.begin(), result.end());
  • @Ramya:这没有意义。 std::wstring 用于窄字符集之外的宽文本。如果您嵌入了空值,则您的输入可能是二进制而不是文本。
  • @MSalters: message value is message { id: 4 word: "software" value: 1 } message { id: 19 word: "technical" value: 0.70992374420166016 } 将此序列化为字符串后,结果字符串中嵌入了空值。我需要将序列化的结果字符串存储到宽字符串中
  • @bashrc 我不明白这是怎么回事。 message.SerializeAsString() 返回 std::string,而不是 const char*,所以 std::string(message.SerializeAsString()) 只是调用常规的复制构造函数,它对包含 NUL 的字符串没有问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
相关资源
最近更新 更多