c語言中的格式化字串
阿新 • • 發佈:2019-02-02
C語言中格式字串的一般形式為: %[標誌][輸出最小寬度][.精度][長度]型別,
其中方括號[]中的項為可選項。
一、型別
我們用一定的字元用以表示輸出資料的型別,其格式符和意義下表所示:
字元 意義
a 浮點數、十六進位制數字和p-計數法(C99)
A 浮點數、十六進位制數字和p-計數法(C99)
c 輸出單個字元
d 以十進位制形式輸出帶符號整數(正數不輸出符號)
e 以指數形式輸出單、雙精度實數
E 以指數形式輸出單、雙精度實數
f 以小數形式輸出單、雙精度實數
g 以%f%e中較短的輸出寬度輸出單、雙精度實數,%e格式在指數小於-4或者大 於等於精度時使用
G 以%f%e中較短的輸出寬度輸出單、雙精度實數,%e格式在指數小於-4或者大於等於精度時使用
i 有符號十進位制整數(與%d相同)
o 以八進位制形式輸出無符號整數(不輸出字首O)
p 指標
s 輸出字串
x 以十六進位制形式輸出無符號整數(不輸出字首OX)
X 以十六進位制形式輸出無符號整數(不輸出字首OX)
u 以十進位制形式輸出無符號整數
示例1
/* 測試常見的輸出型別 */
#include "stdio.h"
#include "conio.h"
main()
{
printf("The program test print style!\n");
/* 以十進位制形式輸出帶符號整數(正數不輸出符號) */
printf("%d\n" , 223);
printf("%d\n" , -232);
printf("\n");
/* 以八進位制形式輸出無符號整數(不輸出字首O) */
printf("%o\n" , 223);
printf("%o\n" , -232);
printf("\n");
/* 以十六進位制形式輸出無符號整數(不輸出字首OX) */
printf("%x\n" , 223);
printf("%x\n" , -232);
printf("\n");
/* 以十進位制形式輸出無符號整數 */
printf("%u\n" , 223);
printf("%u\n" , -232);
printf("\n");
/* 以小數形式輸出單、雙精度實數 */
printf("%f\n" , 223.11);
printf("%f\n" , 232.11111111);
printf("%f\n" , -223.11);
printf("%f\n" , -232.11111111);
printf("\n");
/* 以指數形式輸出單、雙精度實數 */
printf("%e\n" , 223.11);
printf("%e\n" , 232.11111111);
printf("%e\n" , -223.11);
printf("%e\n" , -232.11111111);
printf("\n");
/* 以%f%e中較短的輸出寬度輸出單、雙精度實數 */
printf("%g\n" , 223.11);
printf("%g\n" , 232.111111111111);
printf("%g\n" , -223.11);
printf("%g\n" , -232.111111111111);
printf("\n");
/* 輸出單個字元 */
printf("%c\n" , 'a');
printf("%c\n" , 97);
printf("\n");
/* 輸出單個字元 */
printf("%s\n" , "this is a test!");
printf("%s\n" , "2342o34uo23u");
printf("\n");
getch();
}
二、標誌
標誌字元為-、+、#、空格和0五種,其意義下表所示:
字元 意 義
- 結果左對齊,右邊填空格
+ 輸出符號(正號或負號)
空格 輸出值為正時冠以空格,為負時冠以負號
# 對c,s,d,u類無影響;對o類,在輸出時加字首0;對x類,在輸出時加字首0x或者0X;對g,G 類防止尾隨0被刪除;
對於所有的浮點形式,#保證了即使不跟任何數字,也列印一個小數點字元
0 對於所有的數字格式,用前導0填充欄位寬度,若出現-標誌或者指定了精度(對於整數),忽略
三、輸出最小寬度
用十進位制整數來表示輸出的最少位數。若實際位數多於定義的寬度,則按實際位數輸出,若實際位數少於定義的寬度則補以空格或0。
/* 測試標誌字元為-、+、#、空格四種 */
#include "stdio.h"
#include "conio.h"
main()
{
/* 以十進位制形式輸出帶符號整數(正數不輸出符號) */
printf("*%-10d*\n", 223);
printf("*%+10d*\n" , -232);
printf("*%2d*\n" , 223);
printf("*%#d*\n" , -232);
printf("\n");
getch();
/* 以八進位制形式輸出無符號整數(不輸出字首O) */
printf("*%-10o*\n" , 223);
printf("*%+10o*\n" , -232);
printf("*%o*\n" , 223);
printf("*%#o*\n" , -232);
printf("\n");
getch();
/* 以十六進位制形式輸出無符號整數(不輸出字首OX) */
printf("$%-10x$\n" , 223);
printf("$%010x$\n" , -232);
printf("$% x$\n" , 223);
printf("$%#x$\n" , -232);
printf("\n");
/* 以十進位制形式輸出無符號整數 */
printf("%-10u\n" , 223);
printf("%+10u\n" , -232);
printf("% u\n" , 223);
printf("%#u\n" , -232);
printf("\n");
getch();
/* 以小數形式輸出單、雙精度實數 */
printf("%-10f\n" , 223.11);
printf("%+10f\n" , 232.11111111);
printf("% f\n" , -223.11);
printf("%#f\n" , -232.11111111);
printf("\n");
getch();
/* 以指數形式輸出單、雙精度實數 */
printf("%-10e\n" , 223.11);
printf("%+10e\n" , 232.11111111);
printf("% e\n" , -223.11);
printf("%#e\n" , -232.11111111);
printf("\n");
getch();
/* 以%f%e中較短的輸出寬度輸出單、雙精度實數 */
printf("%-10g\n" , 223.11);
printf("%+10g\n" , 232.111111111111);
printf("% g\n" , -223.11);
printf("%#g\n" , -232.111111111111);
printf("\n");
getch();
/* 輸出單個字元 */
printf("%-10c\n" , 'a');
printf("%+10c\n" , 97);
printf("% c\n" , 'a');
printf("%#c\n" , 97);
printf("\n");
getch();
/* 輸出單個字元 */
printf("%-20s\n" , "this is a test!");
printf("%+20s\n" , "2342o34uo23u");
printf("% 20s\n" , "this is a test!");/* 不足補空格 */
printf("%#s\n" , "2342o34uo23u");
printf("\n");
getch();
}
四、精度
精度格式符以“.”開頭,後跟十進位制整數。本項的意義是:如果輸出數字,則表示小數的位數;如果輸出的是字元,則表示輸出字元的個數;若實際位數大於所定義的精度數,則截去超過的部分。
/* 測試精度 */
#include "stdio.h"
#include "conio.h"
main()
{
printf("%.3d\n" , 5555);
getch();
printf("%.3f\n" , 0.88888);
getch();
printf("%.3f\n" , 0.9999);
getch();
printf("%.4s\n" , "this is a test!");
getch();
}
五、長度
長度格式符為h,l兩種,h表示按短整型量輸出,l表示按長整型量輸出。
h和整數轉換說明符一起使用,表示一個short int 或者unsigned short int型別的數值,
示例:%hu,%hx,%6.4hd
hh和整數轉換說明符一起使用,表示一個short int 或者unsigned short型別的數值,
示例:%hhu,%hhx,%6.4hhd
j和整數轉換說明符一起使用,表示一個intmax_t或者uintmax_t型別的數值,
示例:%jd,%8jx
l和整數轉換說明符一起使用,表示一個long int 或者unsigned long int型別的數值,
示例:%ld,%8lu
ll和整數轉換說明符一起使用,表示一個long int 或者unsigned long int型別的數值(C99),
示例:%lld,%8llu
L和浮點轉換說明符一起使用,表示一個long double的值,示例:%Lf,%10.4Le
t和整數轉換說明符一起使用,表示一個ptrdiff_t值(兩個指標之間的差相對應的型別)(C99),
示例:%td,%12ti
z和整數轉換說明符一起使用,表示一個size_t值(sizeof返回的型別)(C99),
示例:%zd,%12zx
例項
main(){
int a=15;
float b=138.3576278;
double c=35648256.3645687;
char d='p';
printf("a=%d,%5d,%o,%x\n",a,a,a,a);
printf("b=%f,%lf,%5.4lf,%e\n",b,b,b,b);
printf("c=%lf,%f,%8.4lf\n",c,c,c);
printf("d=%c,%8c\n",d,d);
}
a<--15
b<--138.3576278
c<--35648256.3645687
d<--'p'
main()
{
int a=29;
float b=1243.2341;
double c=24212345.24232;
char d='h';
printf("a=%d,%5d,%o,%x\n",a,a,a,a);
/* 其中“%f”和“%lf ”格式的輸出相同,說明“l”符對“f”型別無影響
* “%5.4lf”指定輸出寬度為5,精度為4,由於實際長度超過5故應該按實際位數輸出,小數位數超過4位 * 部分被截去
*/
printf("b=%f,%lf,%5.4lf,%e\n",b,b,b,b);
/* 輸出雙精度實數,“%8.4lf ”由於指定精度為4位故截去了超過4位的部分 */
printf("c=%lf,%f,%8.4lf\n",c,c,c);
/* 輸出字元量d,其中“%8c ”指定輸出寬度為8故在輸出字元p之前補加7個空格*/
printf("d=%c,%8c\n",d,d);
getch();
}
使用printf函式時還要注意一個問題,那就是輸出表列中的求值順序。不同的編譯系統不一定相同,可以從左到右,也可從右到左。Turbo C是按從右到左進行的
main(){
int i=8;
printf("%d\n%d\n%d\n%d\n%d\n",++i,--i,i--,i++,-i--);
}
六、特殊用法
對於m.n的格式還可以用如下方法表示
char ch[20];
printf("%*.*s\n",m,n,ch);
前邊的*定義的是總的寬度,後邊的定義的是輸出的個數。分別對應外面的引數m和n 。我想這種方法的好處是可以在語句之外對引數m和n賦值,從而控制輸出格式。
還一種輸出格式 %n 可以將所輸出字串的長度值賦紿一個變數, 見下例:
int slen;
printf("hello world%n", &slen);
執行後變數被賦值為11。
又查了一下, 看到一篇文章(檢視)說這種格式輸出已經確認為一個安全隱患,並且已禁用。
再搜搜果然這種用法都被用來搞什麼溢位、漏洞之類的,隨便找了一個:格式化字串攻擊筆記。特別注意下%*.*s這種用法
轉自:http://blog.csdn.net/hudashi/article/details/7080078