2017-09-10 281 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位。