我有一个数组:
unsigned char datalog[4];
datalog[0] = 0;
datalog[1] = 0xce;
datalog[2] = 0x50;
datalog[3] = 0xa3;
这些代表十六进制值0xce50a3。其十进制值为13521059。
我需要将此十六进制值转换为十进制数组,最好使用sprintf,以便最终结果为:
finalarray[0] = '1';
finalarray[1] = '3';
finalarray[2] = '5';
finalarray[3] = '2';
finalarray[4] = '1';
finalarray[5] = '0';
finalarray[6] = '5';
finalarray[7] = '9';
我尝试了几种sprintf输入组合,包括将我的十六进制数组连接到unsigned long datalogvalue = 0xce50a3。但sprintf只在转换时读取其第一个字节。
例如:
sprintf(finalarray, "%d", *(unsigned long *)datalog);
的产率:
finalarray[0] = '2';
finalarray[1] = '0';
finalarray[2] = '6';
finalarray[3] = ' ';
.....
206是0xce的十进制表示。所以它只转换第一个十六进制字节,而不是其余的。
有关如何将整个无符号长整数转换为十进制数组的想法吗?
答案 0 :(得分:1)
将char*
转换为unsigned long*
并取消引用该指针的结果取决于系统的字节顺序。除非这个特定计算的效率对于你的程序的性能至关重要,否则不要使用这些技巧。使用简单的逻辑。
int res = (datalog[0] << 24) +
(datalog[1] << 16) +
(datalog[2] << 8) +
datalog[3];
sprintf(finalarray, "%d", res);
如果您需要使用unsigned long
作为类型,请务必在unsigned long
的调用中使用sprintf
的正确格式说明符。
unsigned long res = (datalog[0] << 24) +
(datalog[1] << 16) +
(datalog[2] << 8) +
datalog[3];
sprintf(finalarray, "%lu", res);
答案 1 :(得分:1)
正如其他人提到的那样,尝试按顺序读取数组的字节将依赖于系统,因为Big Endian和Little Endian系统会产生不同的结果。
此外,通过指针欺骗进行类型惩罚是未定义的行为,因为它打破了严格的别名。将pun类型键入char-family数组以外的类型的合法方法涉及使用联合以多种方式表示数据。但是,由于上面的Endian问题,你不应该为这个问题做到这一点,而是采用R Sahu的回答中提到的位移方法。
答案 2 :(得分:1)
一种简单的解决方案,不依赖于endian,int
大小或指针技巧
形成值
// LU to use unsigned long math
((datalog[0]*256LU + datalog[1])*256 + datalog[2])*256 + datalog[3]
打印
sprintf(finalarray, "%lu", value);
共
sprintf(finalarray, "%lu",
((datalog[0]*256LU + datalog[1])*256 + datalog[2])*256 + datalog[3]);
答案 3 :(得分:0)
由于字节顺序,字节不会按照您认为的顺序出现:
#include <stdio.h>
int main(void) {
unsigned char datalog[4];
char finalarray[20] = {0};
datalog[0] = 0xa3;
datalog[1] = 0x50;
datalog[2] = 0xce;
datalog[3] = 0x00;
sprintf(finalarray, "%lu", *(unsigned long*)datalog);
printf("Answer: %s\n", finalarray);
return 0;
}
<强> 输出 强>
Success #stdin #stdout 0s 4180KB
Answer: 13521059
答案 4 :(得分:0)
首先,字节序使得事情在这里变得麻烦。 为了能够将缓冲区重新解释为32位int,在打包时必须考虑字节序。
例如,在我的little-endian系统上,如果将数据转换为32位无符号整数,则数据记录将被解释为:2739981824。
因此,我必须根据以下示例中的datalog2打包我的数据,以获得所需的13521059.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
int main() {
uint8_t datalog[4];
datalog[0] = 0;
datalog[1] = 0xce;
datalog[2] = 0x50;
datalog[3] = 0xa3;
uint32_t temp = *((uint32_t*) datalog);
printf("%u\n", temp); // 2739981824
uint8_t datalog2[4];
datalog2[0] = 0xa3;
datalog2[1] = 0x50;
datalog2[2] = 0xce;
datalog2[3] = 0;
uint32_t temp2 = *((uint32_t*) datalog2);
printf("%u\n", temp2); // 13521059
return 0;
}
但是你要问的是另一个问题。
如果我正确地解释了你的问题,你想得到另一个数组,其中每个小数组成13951059在基数10中,最终在它自己的索引中。
为了做到这一点,你必须能够用每个索引来解决log2(10)位,这是不可能的。
因此,为了获得您建议的包装数组,您必须手动转换它。