将BYTE数组转换为unsigned long long int

时间:2018-02-02 13:28:06

标签: c++

我正在尝试将BYTE数组转换为等效的unsigned long long int值,但我的编码没有按预期工作。请帮助修复它或建议替代方法。

额外信息:这4个字节组合为十六进制数,等效十进制数是输出。假设给定byteArray = {0x00,0xa8,0x4f,0x00},十六进制数为00a84f00,它的等效十进制数为11030272。

#include <iostream>
#include <string>

typedef unsigned char BYTE;

int main(int argc, char *argv[])
{
  BYTE byteArray[4] = { 0x00, 0x08, 0x00, 0x00 };
  std::string str(reinterpret_cast<char*>(&byteArray[0]), 4);
  std::cout << str << std::endl;

  unsigned long long ull = std::strtoull(str.c_str(), NULL, 0);
  printf ("The decimal equivalents are: %llu", ull);


  return EXIT_SUCCESS;
}

我得到以下输出:

The decimal equivalents are: 0

预期产量为:

The decimal equivalents are: 2048

3 个答案:

答案 0 :(得分:4)

当你调用std::strtoull(str.c_str(), NULL, 0);时,它提供的第一个参数是等同于空字符串,因为字符串本质上是一个以空字符结尾的字符序列。

其次,std::strtoull()不会使用字节序列进行转换,而是使用字符串的字面含义进行转换。即,您2048将获得std::strtoull("2048", NULL, 10)

另一点需要注意的是unsigned long long是64位数据类型,而您的字节数组只提供32位。您需要用零填充其他32个字节以获得正确的结果。我使用直接分配,但您也可以在此使用std::memset()

您想要做的是:

ull = 0ULL;
std::memcpy(&ull, byteArray, 4);

鉴于您的平台有little-endian,结果应为2048

答案 1 :(得分:3)

首先必须记住的是,字符串实际上是 以null结尾的 字符串。其次,字符串是一串字符,这不是你拥有的。第三个问题是你有一个四个字节的数组,它对应于一个无符号的32位整数,你想要一个(至少)64位类型,它是8个字节。

您可以使用临时变量,对std::memcpy的简单调用和分配来解决所有这些问题:

uint32_t temp;
std::memcpy(&temp, byteArray, 4);
ull = temp;

当然,这假设endianness是正确的。

请注意,我使用的是std::memcpy而不是std::copy(或std::copy_n),因为明确提到std::memcpy能够以这种方式绕过严格的别名,而我不会# 39;认为std::copy函数是。此外,std::copy函数更多用于复制元素而不是匿名字节(即使它们也可以这样做,但语法更笨拙)。

答案 2 :(得分:2)

鉴于答案正在使用char byteArray[] = { 0x00, 0x08, 0x00, 0x00 }; uint32_t cp; std::copy(byteArray, byteArray + sizeof(cp), reinterpret_cast<char*>(&cp)); ,我想指出,这是一种更惯用的方法:

std::memcpy

robotscp类似,但它是C ++的做法。

请注意,您需要将输出变量char *的地址强制转换为:unsigned char *signed char *std::byte *<img src="@Url.Content("~/data/pic.png")" /> 之一,因为否则操作不会以字节为导向。