错误地将两个字节数组转换为c中的short

时间:2019-03-22 19:22:55

标签: c

我正在尝试将2个字节的数组转换为无符号的短字节。

这是转换的代码:

short bytesToShort(char* bytesArr)
{
    short result =(short)((bytesArr[1] << 8)|bytesArr[0]);
    return result;
}

我有一个InputFile存储字节,我通过循环读取字节(每次2个字节),并以这种方式将其存储在char N [] arr中:

char N[3];
N[2]='\0';

while(fread(N,1,2,inputFile)==2)

当N [0] = 0的(hex)值正确时,否则计算错误,例如:

0x62(N [0] = 0x0,N [1] = 0x62)将返回98(简短值),以十六进制显示0x166(N [0] = 0x6,N [1 ] = 0x16)将返回5638(简短值)。

2 个答案:

答案 0 :(得分:3)

首先,通常最好对原始二进制数据的字节使用类型NAME AGE admin 35d cloud-provider 35d cluster-admin 35d cluster-autoscaler 35d edit 35d gce:beta:kubelet-certificate-bootstrap 35d gce:beta:kubelet-certificate-rotation 35d gce:cloud-provider 35d kubelet-api-admin 35d view 35d ,因为它可以正确表达您正在处理的内容的语义。尽管unsigned char类型虽然经常被用作“字节”的同义词,但最好保留给实际上是字符性质的数据。

如果还要对字节值执行算术运算,则几乎肯定要用char而不是unsigned char,因为char的符号是实现定义的。它的实现方式确实有所不同,在许多常见的实现方式中,char signed

话虽如此,您的主要问题似乎很简单。你说

  

166(十六进制,N [0] = 6,N [1] = 16)将返回5638(短值)。

,但打包为两字节的小字节序数组的0x166将为(N [0] = 0x66,N [1] = 0x1)。您编写的内容对应于0x1606,实际上与十进制5638相同。

答案 1 :(得分:1)

问题是由于使用了char而引起的符号扩展。您应该改用unsigned char

#include <stdio.h>

short bytesToShort(unsigned char* bytesArr)
{
    short result = (short)((bytesArr[1] << 8) | bytesArr[0]);
    return result;
}

int main()
{
    printf("%04x\n", bytesToShort("\x00\x11")); // expect 0x1100
    printf("%04x\n", bytesToShort("\x55\x11")); // expect 0x1155
    printf("%04x\n", bytesToShort("\xcc\xdd")); // expect 0xddcc

    return 0;
}

注意:代码中的问题不是OP提出的。问题是在输入"\xcc\xdd"上返回错误的结果。它将产生0xffcc0xddcc