我正在尝试将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
答案 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
robots与cp
类似,但它是C ++的做法。
请注意,您需要将输出变量char *
的地址强制转换为:unsigned char *
,signed char *
,std::byte *
或<img src="@Url.Content("~/data/pic.png")" />
之一,因为否则操作不会以字节为导向。