1. 程式人生 > >char陣列和十六進位制格式化sprintf

char陣列和十六進位制格式化sprintf

char ch[2];

sprintf(ch, "%x", 100);
printf("字串%%s輸出:%s\n", ch);
printf("字元%%c輸出ch:%c\n", ch);
printf("字元%%c輸出ch[0]:%c\n", ch[0]);
printf("字元%%c輸出ch[1]:%c\n", ch[1]);
printf("十六進位制%%x輸出ch:%x\n", ch);
printf("十六進位制%%x輸出ch[0]:%x\n", ch[0]);
printf("十六進位制%%x輸出ch[1]:%x\n", ch[1]);
printf("十進位制%%d輸出ch:%d\n", ch);
printf("十進位制%%d輸出ch[0]:%d\n", ch[0]);
printf("十進位制%%d輸出ch[1]:%d\n", ch[1]);

輸出:
字串%s輸出:64
字元%c輸出ch:>
字元%c輸出ch[0]:6
字元%c輸出ch[1]:4
十六進位制%x輸出ch:22ff3e
十六進位制%x輸出ch[0]:36
十六進位制%x輸出ch[1]:34
十進位制%d輸出ch:2293566
十進位制%d輸出ch[0]:54
十進位制%d輸出ch[1]:52

說明:
int sprintf( char *buffer, const char *format, [ argument] … );
sprintf指的是字串格式化命令,主要功能是把格式化的資料寫入某個字串中。
100十六進位制為64,ch中存入'6''4',以%c字元輸出時ch[0]='6',ch[1]='4'
以%d十進位制數輸出時,對應這兩個字元的ACSII碼為 54 52
同理,%x十六進位制輸出時,對應54 52的十六進位制36 34

printf("字元%%c輸出ch:%c\n", ch);
printf("十六進位制%%x輸出ch:%x\n", ch);
printf("十進位制%%d輸出ch:%d\n", ch);
這兩個輸出的結果是不好理解的,剛開始以為是由高位54低位52組成的一個十六位數,測試了多次結果都不對,後來在VS裡面測試發現這個結果每次都是變化的,才想到這是指標,也就是ch的地址。
char[]是“特殊的”陣列,是由char組成的字串,陣列名代表地址,也是指向存放該陣列的地址的指標。對於陣列名,當以%s輸出時,就將各個字元以整體字串的形式輸出,以數字的形式(包括%c %d %x)時,輸出地址,而%c是1個位元組,地址是4個位元組,所以地址被擷取為1個位元組後輸出,將4個位元組的int型別擷取為1個位元組char型別,測試後%d會輸出63,對應ASCII為'?'

PS:發現Linux和Windows的編譯器區別,GCC中同一程式多次執行時變數地址保持不變,而在VS中每次都會變化。

 


sprintf 是個變參函式。

可變引數函式顧名思義,就是函式引數個數是未知的是可變的。sprintf中[ argument]的引數和format中的格式化符號一一對應。

 

sprintf 對於寫入buffer的字元數是沒有限制的,這就存在了buffer溢位的可能性。

例如:

char buffer[2];
sprintf(buffer, "%x", 1000);
printf("格式化後buffer:%s\n長度:%d\n", buffer, strlen(buffer));

輸出:
格式化後buffer:3e8
長度:3

說明:
首先定義一個長度為2的char陣列buffer,然後使用sprintf將1000以十六進位制存入buffer,1000十六進位制為3e8,所有buffer長度變為3,發生溢位。

 

4位元組“暴力”擷取1位元組

union A
{
	int i;
	char c;
};
union A a;
a.i=2293567;
printf("擷取後:十進位制%d,字元%c\n", a.c, a.c);

輸出:
擷取後:十進位制63,字元?