【问题标题】:4 chars to int in c++在 C++ 中将 4 个字符转换为 int
【发布时间】:2014-11-29 12:53:24
【问题描述】:

我必须从一个文件中读取 10 个字节,最后 4 个字节是一个无符号整数。但我得到了一个 11 字符字节长的字符数组/指针。如何将最后 4 个字节(末尾没有零终止字符)转换为无符号整数?

//pesudo code
char *p = readBytesFromFile();
unsigned int myInt = 0;
for( int i = 6; i < 10; i++ )
    myInt += (int)p[i];

正确吗?对我来说似乎不正确。

【问题讨论】:

  • 使用memcpy*(int*)(p+6) (1) 可能会遇到对齐问题并且 (2) 违反严格的别名。字节顺序也可能是一个问题。
  • 您实际上需要将不同字节的位移动到适当的位置。取决于传输值的字节顺序。循环中的赋值可能是myInt = myInt &lt;&lt; 8 | static_cast&lt;unsigned char&gt;(p[i])。或者,您可能希望反向循环循环。
  • 伙计们,这些都应该变成答案,而不是 cmets。

标签: c++ int arrays


【解决方案1】:

试试myInt = *(reinterpret_cast&lt;unsigned int*&gt;(p + 6));

这需要第 6 个字符的地址,重新解释为指向无符号整数的指针,然后返回它指向的 (无符号整数) 值。

【讨论】:

  • 这对于字节序可能很危险
  • 因为没有unsigned int 变量可供查看。我们正在查看需要指针的任意内存。出于这个原因,reinterpret_cast 仅适用于指针。
【解决方案2】:

我同意之前的回答,但我想补充一点,如果文件是使用不同的字节序创建的,此解决方案可能无法 100% 工作。

我不想用额外的信息让您感到困惑,但请记住,当您直接从文件投射时,字节顺序可能会给您带来问题。

这是关于字节顺序的教程:http://www.codeproject.com/Articles/4804/Basic-concepts-on-Endianness

【讨论】:

    【解决方案3】:

    以下代码可能工作:

    myInt = *(reinterpret_cast<unsigned int*>(p + 6));
    

    如果:

    • 不存在对齐问题(例如,在 GPU 内存空间上,如果不提供某些保证,这很可能会崩溃)。
    • 您可以保证系统字节序与用于存储数据的字节序相同
    • 您可以确定sizeof(int) == 4,这在任何地方都得到保证

    如果不是,正如Dietmar 建议的那样,您应该遍历您的数据(根据字节顺序向前或向后)并执行类似的操作

    myInt = myInt << 8 | static_cast<unsigned char>(p[i])
    

    这是对齐安全的(它应该在每个系统上)。还是要注意第 1 点和第 3 点。

    【讨论】:

    • 严格别名。您无法通过 unsigned int 类型的 glvalue 访问一堆字符的存储值。
    • 另一个不这样做的理由。
    【解决方案4】:

    也许使用联合是一种选择?我认为这可能有效; 更新:是的,它有效。

    union intc32 {
        char c[4];
    
        int v;
    };
    
    int charsToInt(char a, char b, char c, char d) {
        intc32 r = { { a, b, c, d } };
        return r.v;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-01
      • 1970-01-01
      • 2018-06-10
      • 2011-07-11
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 2012-05-20
      相关资源
      最近更新 更多