2017-09-10 467 views
0

我具有与十六进制数据一个C程序,其欲迭代代码,例如用于打印出每个十六进制的字节:Ç打印十六进制字节

char input[] = "\x31\xd2\xb2\x30"; 
for (int i = 0; i < strlen(input); i++) { 
    printf("%02X\n", input[i]); 
} 

但是,输出是不是我期望的,例如在上述打印:

31 
FFFFFFD2 
FFFFFFB2 
30 

我也试图投输出作为(unsigned int),但是我接收到相同的输出。

有人可以用这个简单的脚本指出问题吗?

+1

在你的系统上,'char'可能是'signed'。所以数据'\ xd2'是负数。您将该值传递给'printf',并将其提升为也被签名的'int'。但是格式说明符'%X'期待'unsigned int'并相应地解释二进制数据。它是*未定义的行为*。 –

回答

1

传递给printf的参数是符号扩展,除非你施放他们为无符号类型是这样的:

printf("%02X\n", (unsigned char)input[i]); 
+0

哎呀,你是对的。我使用了一个unsigned int,但当然这是一个字符。 – user1220022

0

char input[]必须是unsigned char input[]。这就是你存储二进制字节的方式。

1

printf("%02X")期待一个无符号整数;通过类型为char(和0xD2类型为char的负值为负值)的负值将导致将负数字值提升为32位无符号整数,从而最终填充了前导位1并产生了0xFFFFFFD2。然后打印。

为了克服这个问题,你可以“告诉” printf采取作为8位值提供的值:

printf("%02hhX\n", input[i]) 

另一种选择是申报inputunsigned char,因为那时0xD2将不被视为“负面”,并晋升到32位将如预期:

unsigned char input[] = "\x31\xd2\xb2\x30"; 

注意,然后strlen需要投输入,即strlen((char*)intput)

0
// You can use like this 

char input[] = "\x31\xd2\xb2\x30"; 

for (int i = 0; i < strlen(input); i++) { 
    printf("%02X\n", input[i] & 0xff); 
} 

Output: 
31 
D2 
B2 
30 

它将屏蔽掉高位并只保留低8位。