十六进制的十六进制值数组

时间:2018-03-07 12:47:09

标签: c

我正在读取从文件到数组的HEX值。

我正在使用的缓冲区部分包含4个字节的十六进制 - > CE EE 00 00

unsigned int fileLocationOffset = 64;
unsigned char fileSize[4]; //This is actually in a struct. 
                           //Putting here for purposes of this question
unsigned char buff[sizeOfRoot];

fseek(fp, startOfRoot, SEEK_SET); //Seek to point in file fp
fread(buff, 1, sizeOfRoot, fp);   //Save contents to a buffer

//Read in 4 Bytes backwards to put as Big-Endian
for(int z = 31; z > 27; z--){
    fileSize[31 - z] = buff[fileLocationOffset + z];
}

//TEST: Print Values at each element to see if correct
for(int z = 0; z < 4; z++){
  printf("%X ", fileSize[z]);
}
// Output: 0 0 EE CE <- Correct

所以,我知道我的fileSize数组包含正确的值,但现在我需要将0x00EECE转换为小数。

有人可以告诉我该如何做这件事吗?

5 个答案:

答案 0 :(得分:0)

您如何处理数据?

十六进制和十进制等概念仅在打印数据时适用。

的输出是什么
printf("%d", *(int *)filesize);

答案 1 :(得分:0)

您先前的评论表明您使用的是小型机器。

文件中的值也是小端。

为什么要改变你的结束?

参见以下测试程序:

// big endian
unsigned char fileSize[4] = { 0x0, 0x0, 0xEE, 0xCE };

// little endian
unsigned char fileSize2[4] = { 0xCE, 0xEE, 0x00, 0x00 };

int main(void)
{
    int i;


    // Output: 0 0 EE CE <- Correct
    for (i = 0; i < sizeof fileSize; i++)
        printf("%02x ", fileSize[i]);

    printf("\n");

    for (i = 0; i < sizeof fileSize2; i++)
        printf("%02x ", fileSize2[i]);

    printf("\n");

    printf("%u\n", *(int *)fileSize);
    printf("%u\n", *(int *)fileSize2);
}

输出(在电脑上):

00 00 ee ce
ce ee 00 00
3471704064
61134

答案 2 :(得分:0)

好的,所以你有大端序的int值的字节,并想要构建值。您可以简单地将字节放入uint32_t变量:

uint32_t bytes_to_int(unsigned char *bytes) {
    uint32_t val = 0;
    for(int i=0; i<4; i++) {
        val <<= 8;      //shift 8 positions to the right
        val |= *bytes++;
    }
    return val;
}

有了它,以下测试程序:

int main() {
    unsigned char foo[] = { 0, 0, 0xee, 0xce };
    unsigned val = bytes_to_int(foo);
    printf("%d - 0x%x\n", val, val);
    return 0;
}

按预期输出:

61134 - 0xeece

答案 3 :(得分:0)

您可以将数据提取为单个无符号32位整数,并且几乎可以直接使用(当然,这取决于字节序问题)。

也许是这样的:

uint32_t fileSize;
memcpy(&fileSize, buff[fileLocationOffset + 28], 4);

然后,对于字节序问题,如果您使用的是Linux,则可以使用be32toh(请参阅例如this endian manual page)将big-endian转换为主机编码(如果您的主机没有,则不会执行任何操作系统是大端的):

fileSize = be32toh(fileSize);

Windows API中最接近此功能的是ntohl,可以类似的方式使用。

为此实现绝对字节交换功能甚至宏并不难:

inline uint16_t byteswap16(uint16_t value)
{
    return (value & 0xff) << 8 | (value >> 8);
}

inline uint32_t byteswap32(uint32_t value)
{
    return byteswap16(value & 0xffff) << 16 | byteswap16(value >> 16);
}

...
fileSize = byteswap32(fileSize);
...

答案 4 :(得分:0)

Serge Ballesta给出的答案是正确的,但还有另外一个肮脏但很短的伎俩。

int main() {
char data[]={0xce,0xee,0,0};
int *ptr;
ptr=data;
printf("%d\n",*ptr);
//if you want to store this result
int x=*ptr;
printf("%d\n",x);
return 0;
}

这样你甚至不必扭转你的字节。

输出:

  

61134

     

61134

这里编译器本身负责结束