将 BYTE 数组转换为无符号长整型

Convert BYTE array into unsigned long long int

本文关键字:无符号 长整型 转换 BYTE 数组      更新时间:2023-10-16

我正在尝试将 BYTE 数组转换为等效的无符号长整整型值,但我的编码没有按预期工作。请帮助修复它或建议另一种方法。

额外信息:这 4 个字节组合为十六进制数,等效的十进制数是输出。假设对于给定的字节数组= {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

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

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

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

您要做的是:

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

鉴于您的平台具有小端序,结果应该是2048

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

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

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

当然,这假设字节序是正确的。


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

鉴于答案是使用 std::memcpy ,我想指出有一种更惯用的方法来执行此操作:

char byteArray[] = { 0x00, 0x08, 0x00, 0x00 };
uint32_t cp;
std::copy(byteArray, byteArray + sizeof(cp), reinterpret_cast<char*>(&cp));

std::copystd::memcpy相似,但却是C++方法。

请注意,你需要将输出变量cp的地址转换为:char *unsigned char *signed char *std::byte *,否则操作将不是面向字节的。