【问题标题】:Convert std::string to uint16_t*将 std::string 转换为 uint16_t*
【发布时间】:2014-10-25 11:59:29
【问题描述】:

我已将一些数据序列化为 ostream,以通过设备文件发送。以二进制格式。

打印 ostream 的内容时我得到这样的输出,这很好。

现在我需要使用某种算法来计算校验和:

因为我使用的是文件流,所以我有字符串格式的二进制数据:

例如:

46774101101140410MyMakeMyModel10000....

我想使用算法计算校验和..

就像

校验和由所有 16 位字的 2 补码相加计算得到

如果八位字节数为奇数,则最终八位字节假定为在 MSB 中填充的 16 位 0。

我正在寻找解决方案,请建议一个万无一失的方法输入是字符串或字符 *

谢谢

【问题讨论】:

  • 此代码具有未定义的行为。如果输入字符串开始添加一个奇数地址,执行此操作很可能引发硬件异常。
  • 你好,kerrek,请不要查看代码,我的意思是我需要进行类似的校验和计算,但我没有 uint16_t* 而不是 ostream

标签: c++


【解决方案1】:

您的代码通过破坏严格的别名规则来引发未定义的行为。如果您不能确定 data 指向的数据是否与 uint16_t 正确对齐,那么这甚至可能成为一个实际问题(正如 Kerrek 在 cmets 中所提到的)。

对于string,您必须将内容复制到uint16_t-array 并从那里开始工作。
它可能看起来像这样:

std::string str;
// Put some data into str

std::vector<std::uint16_t> array((str.size() + sizeof(std::uint16_t) - 1) / sizeof std::uint16_t);
std::copy_n(str.data(), str.size(), reinterpret_cast<char*>(&array[0]));

// Work with array

【讨论】:

  • 一个奇怪的提示是,您的代码依赖于 make_unique 初始化数组(它会这样做),否则您最终可能会从未初始化的变量中读取。
  • (虽然我实际上不确定它是否允许覆盖对象表示的一部分。)
  • 仅此代码 sn-p 将使我转向另一种语言。这不漂亮
  • @davbryn 如果您正在处理 C++,迁移到另一种语言总是一个好主意。
  • @KerrekSB 我知道最后一个字节可能未初始化。反正我忘了当初为什么选择unique_ptr,就改成了vector
【解决方案2】:

似乎您在这里的主要困难是将std::string 转换为整数。 您可以使用std::string::substr 将您的字符串分解为您需要的任意大小的块,并将每个块转换为一个整数。

可能来自this question 的代码可以显示该方法。

【讨论】:

    猜你喜欢
    • 2016-01-28
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    相关资源
    最近更新 更多