轉換說明符速查
| 符號 | 輸出類型 | 示例 | 備註 |
%d, %i | 有符號十進制整數 | 42, -7 | |
%u | 無符號十進制整數 | 42 | |
%o | 八進制 | 052 | 無前綴 |
%x, %X | 十六進制 | 2a, 2A | 無前綴 |
%f | 定點浮點數 | 3.140000 | 默認 6 位小數 |
%e, %E | 科學計數法 | 3.140000e+00 | |
%g, %G | 自動選 f/e,去尾零 | 3.14 | 精度為有效數字 |
%a, %A | 十六進制浮點數 | 0x1.91eb851eb851fp+1 | C99 |
%c | 單字符 | A | |
%s | 字符串 | hello | 以 \0 結束 |
%p | 指針地址 | 0x7ffe... | 實現定義格式 |
%% | 字面 % | % | |
標志字符
| 標志 | 含義 | 示例 |
- | 左對齊(默認右對齊) | %-10d |
+ | 有符號數總顯示正負號 | %+d → +42 |
空格 | 正數前加空格,負數顯示 - | % d → 42 |
# | 替代形式:o 加 0,x/X 加 0x/0X,f/e/g 強制顯示小數點 | %#x → 0x2a |
0 | 寬度填充用 0 而非空格(數值類型) | %05d → 00042 |
完整格式語法
%[標志][最小寬度][.精度][長度]轉換符
最小寬度
%10d:至少佔 10 列,不足左填空格(或 0)。
%*d:寬度由參數指定 printf("%*d", 10, 42)。
精度
- 整數(
d,i,o,u,x,X):最小數字位數,不足前補 0。
- 浮點數(
f,F,e,E):小數點後位數。
- 字符串(
s):最大字符數(截斷)。
%.*s:精度由參數指定。
長度修飾符
| 修飾符 | 對應類型 | 示例 |
hh | signed char, unsigned char | %hhd |
h | short, unsigned short | %hd |
l | long, unsigned long, double(%lf 等同 %f) | %ld, %lf |
ll | long long, unsigned long long | %lld |
j | intmax_t, uintmax_t | %jd |
z | size_t | %zu |
t | ptrdiff_t | %td |
L | long double | %Lf |
實戰示例
printf("%-10s %08x %+06.2f\n", "Item", 0x2A, 3.14);
// 輸出: Item 0000002a +03.14
printf("Pointer: %p\n", (void*)0xdeadbeef);
// 輸出: Pointer: 0xdeadbeef
printf("%.2s\n", "Hello"); // He
printf("%5.2s\n", "Hello"); // He
printf("%-5.2s\n", "Hello"); // He
printf("%#x %#o\n", 42, 42); // 0x2a 052
常見坑與避坑指南
- 參數類型不匹配:
%d 對應 long 會導致未定義行為。使用 %ld 或強轉。
%s 無 \0 結束:會越界讀取。用 %.ns 限制長度或確保字符串結尾。
- 浮點數傳遞:
float 會自動提升為 double,%f、%lf 在 printf 中等價;但 scanf 中必須用 %lf 讀 double。
- 指針打印:務必轉
(void*) 配合 %p,否則行為未定義。
- 長度修飾符缺失:64 位系統
long 可能 8 字節,%d 只取低 4 字節。養成用 %ld/%zu/%td 習慣。
進階:自定義輸出
C99 <inttypes.h> 提供 PRId64、PRIuPTR 等宏,確保跨平台格式化正確:
#include <inttypes.h>
int64_t x = 1234567890123LL;
printf("x = %" PRId64 "\n", x);
總結
掌握 printf 格式化字符串,能精確控制輸出佈局、避免類型不匹配 Bug、提升日誌可讀性。建議收藏本表,編寫格式化代碼時隨時查閱。