格式說明符是 C 語言輸入輸出函數 (printf, scanf 等) 的核心,掌握其完整語法能避免大量難以除錯的格式化錯誤。本文提供標準 C (C99/C11) 完整規範速查表。
%[旗標][寬度][.精度][長度]類型
% 與 類型 為必填| 類型 | 對應資料型態 | printf 輸出 | scanf 輸入 |
|---|---|---|---|
d, i | int | 有號十進位整數 | 有號十進位 (i 可自動識別 0x/0 開頭) |
u | unsigned int | 無號十進位整數 | 無號十進位 |
o | unsigned int | 無號八進位 (無前綴) | 無號八進位 |
x, X | unsigned int | 無號十六進位 (小寫/大寫) | 無號十六進位 |
f, F | double | 定點小數 (小寫/大寫 nan/inf) | 浮點數 |
e, E | double | 科學記號 (小寫/大寫 e) | 浮點數 |
g, G | double | 自動選 f 或 e (短者),去尾隨 0 | 浮點數 |
a, A | double | 十六進位浮點數 (C99) | 浮點數 (C99) |
c | int (字元) | 單一字元 | 單一字元 (不跳過空白) |
s | char* | 字串 (至空字元) | 字串 (跳過前導空白,讀至空白) |
p | void* | 指標位址 (實作定義格式) | 指標位址 |
n | int* | 不輸出,寫入目前已輸出字元數 | 不讀取,寫入已讀取字元數 |
% | 無 | 輸出 % 字元 | 匹配輸入 % |
| 旗標 | 說明 | 適用類型 |
|---|---|---|
- | 左對齊 (預設右對齊) | 所有 |
+ | 有號數值必顯示正負號 | d,i,f,e,E,g,G |
空格 | 正數前加空格,負數加負號 | d,i,f,e,E,g,G |
# | 替代形式:o 加 0 前綴,x/X 加 0x/0X,f/e/g 強制顯示小數點,g/G 保留尾隨 0 | o,x,X,f,e,E,g,G |
0 | 左側補 0 而非空格 (遇 - 旗標或精度時失效) | d,i,o,u,x,X,f,e,E,g,G |
' | 依區域設定加千分位分隔符 (C99, GNU 擴展) | d,i,u,f,F,g,G |
* 從參數讀取 (printf("%*d", width, val)). 後接數字或 *
d,i,o,u,x,X:最小位數,不足前補 0f,F,e,E:小數點後位數 (預設 6)g,G:最大有效數字總數s:最大輸出字元數 (截斷)| 修飾符 | 對應型態 (printf) | 對應型態 (scanf) |
|---|---|---|
hh | signed char / unsigned char | signed char* / unsigned char* |
h | short / unsigned short | short* / unsigned short* |
l (ell) | long / unsigned long / double (同無修飾) | long* / unsigned long* / double* |
ll (ell ell) | long long / unsigned long long | long long* / unsigned long long* |
j | intmax_t / uintmax_t | intmax_t* / uintmax_t* |
z | size_t / ssize_t | size_t* |
t | ptrdiff_t | ptrdiff_t* |
L | long double | long double* |
printf("%05d\n", 42); // 00042 (寬度5, 補0)
printf("%-10s\n", "hi"); // "hi " (左對齊)
printf("%+d %+d\n", 1, -1); // "+1 -1" (強制符號)
printf("%#x\n", 255); // "0xff" (替代形式)
printf("%.2f\n", 3.14159); // "3.14" (精度2)
printf("%.*f\n", 3, 1.2); // "1.200" (精度來自參數)
printf("%lld\n", 1LL<<60); // long long 輸出
scanf("%zu", &size_var); // 讀取 size_t
%[...] 掃描集:%[abc] 只讀 a/b/c,%[^abc] 讀非 a/b/c,%[^\n] 讀整行%*d 抑制賦值:讀取但不存入變數%n 獲取已讀字元數:scanf("%d%n", &val, &cnt)%f:float 會自動提升為 double,%lf 在 printf 中合法但多餘 (C99 允許),scanf 必須 用 %lf 讀 doublescanf("%19s", buf) 限制寬度 (buf[20])scanf(" %c", &ch) 前加空格跳過空白字元printf("%p", (void*)ptr) 強制轉 void* 避免警告long long 用 %lld,size_t 用 %zu,int64_t 用 PRId64 (inttypes.h)為了跨平台可移植性,定長整數型態應使用宏:
printf("int32_t: %" PRId32 "\n", val32);
printf("uint64_t: %" PRIu64 "\n", val64);
scanf("%" SCNd32, &val32);
格式說明符看似瑣碎,實則是 C 語言 I/O 正確性的基石。建議:
%d, %s, %.2f, %p) 熟記於心inttypes.h 宏將此表存為備忘單,下次遇到格式化輸出怪異行為時,對照檢查即可快速定位問題。