格式字符串完整語法
%[flags][width][.precision][length]specifier
各組件詳解
標誌 Flags
| 標誌 | 含義 |
- | 左對齊(默認右對齊) |
+ | 有符號數始終顯示正負號 |
空格 | 正數前加空格,負數前加負號 |
# | 替代形式:0x/0/小數點強制顯示 |
0 | 數值右對齊時前導填 0(被 - 覆蓋) |
寬度 Width 與精度 Precision
width:最小字符數,不足填充;* 表示由下一參數指定。
.precision:整數——最小位數(前導 0);浮點——小數位數;字符串——最大字符數;.* 由參數指定。
長度修飾符 Length Modifier
| 修飾符 | 適用類型 | 示例 |
hh | char (signed/unsigned) | %hhd |
h | short | %hd |
l | long/double (printf) | %ld, %lf |
ll | long long | %lld |
L | long double | %Lf |
z | size_t | %zu |
t | ptrdiff_t | %td |
j | intmax_t | %jd |
轉換規格符 Specifier 速查
| 符號 | 輸出類型 | 備註 |
d, i | 有符號十進制整數 | |
u | 無符號十進制整數 | |
o | 八進制無符號 | # 加前綴 0 |
x, X | 十六進制無符號 | # 加 0x/0X |
f, F | 十進制浮點 | 默認 6 位小數 |
e, E | 科學計數法 | 默認 6 位小數 |
g, G | 自動選 f/e | 去尾部 0,# 保留小數點 |
a, A | 十六進制浮點 (C99) | 0x1.23p+4 |
c | 單字符 | int 參數轉 unsigned char |
s | 字符串 | char*,precision 截斷 |
p | 指針地址 | 實現定義格式,通常 0x... |
n | 已寫入字符數 | 指向 int*,安全風險 |
% | 字面 % | %% |
進階技巧與避坑指南
動態寬度/精度
printf("%*.*s\n", width, precision, str); // 寬度、精度由參數傳入
字符串截斷與補齊
printf("%.3s\n", "123456"); // 輸出 "123"
printf("%10.3s\n", "123456"); // 輸出 " 123" (右對齊)
printf("%-10.3s\n", "123456");// 輸出 "123 " (左對齊)
浮點數陷阱
float 傳入 printf 自動提升為 double,用 %f 即可;%lf 在 printf 中等同 %f (C99)。
%g 默認 6 位有效數字(含整數部分),非小數位。
- 極大/極小值自動切換科學計數法。
安全警示
- 格式字符串漏洞:
printf(user_input) 極其危險,必須用 printf("%s", user_input)。
%n 可寫入內存,配合格式字符串漏洞可任意寫內存,禁用或極謹慎使用。
- 參數類型與格式不匹配屬未定義行為(如
%d 對應 long long)。
實戰範例:對齊表格輸出
printf("%-20s %10d %8.2f %%\n", "Item", 12345, 99.5);
輸出:
Item 12345 99.50 %
總結
printf 格式系統強大且複雜。掌握標誌-寬度-精度-長度-規格五要素組合,配合類型匹配與安全意識,即可輸出既美觀又正確的文本。建議收藏本表作為速查手冊。