printf、sscanf進行16進位制資料轉換問題
阿新 • • 發佈:2019-02-10
問題1:原程式的目的是將字串形式的mac地址存放在char型陣列當中(如有更好的獲取方法留言說下,謝謝),程式碼如下,在mac執行如下程式碼後,變數int型值發生了變化。
執行結果如下:#include <stdio.h> typedef unsigned int uint32; int main(void) { int num = 1; char str_mac[] = "7f:ab:ee:af:55:76"; unsigned char mac[6] = {0}; printf("num = %d\n", num); sscanf((char *)str_mac, "%2x:%2x:%2x:%2x:%2x:%2x", (uint32 *)&mac[0],(uint32 *)&mac[1],(uint32 *)&mac[2],(uint32 *)&mac[3],(uint32 *)&mac[4],(uint32 *)&mac[5]); printf("&mac[5] = %p; &num = %p\n", &mac[5], &num); printf("num = %d\n", num); printf("mac : [%x:%x:%x:%x:%x:%x]\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return 0; }
➜ sscanf ./a.out
num = 1
&mac[5] = 0x7fff586b6897; &num = 0x7fff586b6898
num = 0
mac : [7f:ab:ee:af:55:76]
原因是%x匹配unsigned int型指標,在對mac[5]地址進行賦值操作的時候,是對mac[5]為起始的四個位元組進行了賦值操作,影響到了變數i的值。
修改後的程式碼如下(如有更好的方法,留言說下,謝謝):
int main(void) { int num = 1; char str_mac[] = "7f:ab:ee:af:55:76"; unsigned int tmp_mac[6] = {0}; unsigned char mac[6] = {0}; int i = 0; printf("num = %d\n", num); sscanf((char *)str_mac, "%2x:%2x:%2x:%2x:%2x:%2x", (uint32 *)&tmp_mac[0],(uint32 *)&tmp_mac[1],(uint32 *)&tmp_mac[2],(uint32 *)&tmp_mac[3],(uint32 *)&tmp_mac[4],(uint32 *)&tmp_mac[5]); for (i = 0; i < sizeof(mac); i++) { mac[i] = tmp_mac[i]; } printf("num = %d\n", num); printf("mac : [%x:%x:%x:%x:%x:%x]\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return 0; }
問題2: 執行如下程式:
執行結果如下:#include <stdio.h> int main(void) { char a = 0xbf; printf("char_a = %2x \n", a); unsigned char ua = 0xbf; printf("unsigned_char_a = %2x \n", ua); char b = 0x7f; printf("char_b = %2x \n", b); int c = 0xbf; printf("int_c = %2x \n", c); int d = 0x7f; printf("int_d = %2x \n", d); return 0; }
➜ hex ./a.out
char_a = ffffffbf
unsigned_char_a = bf
char_b = 7f
int_c = bf
int_d = 7f
為什麼char_a列印的值前面多了ffffff,其它的都是想要的列印值。 原因是沒有注意變數型別的取值範圍! char 型變數的取值範圍是 (-128,127);而0xbf的值是191,超出了其範圍大小,實際對應的十進位制數值是-65,負數在計算機中以補碼的形式儲存。 printf所要求的輸出格式是%x,其對應的變數型別是unsigned int,所以-65以unsigned int型別來進行解讀。 -65在計算機中的表示方式轉化如下: 1、0000 0000 0000 0000 0000 0000 0100 0001 先進行取反 1111 1111 1111 1111 1111 1111 1011 1110 2、在上面轉化的基礎上加1後得 1111 1111 1111 1111 1111 1011 1111,這個就是在計算機中的儲存形式 3、將上面計算機中的儲存形式按unsigned int進行解讀得到的值就是 ffffffbf 參考連結: http://www.ruanyifeng.com/blog/2009/08/twos_complement.html