首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言 printf/scanf 格式符完全指南:從入門到避坑

     編輯:關於C語言

格式字符串通用語法

%[標志][最小寬度][.精度][長度]類型

方括號內為可選項。掌握每個欄位含義,是輸出漂亮、輸入正確的基礎。

一、 類型字符:核心骨架

字符含義適用類型
d, i有符號十進制整數int, short
u無符號十進制整數unsigned int
o八進制無符號 (無前綴)unsigned int
x, X十六進制無符號 (無前綴)unsigned int
f, F十進制小數形式float, double
e, E科學計數法float, double
g, G%f 或 %e 中較短者float, double
c單字符char (提升為 int)
s字符串char *
p指針地址void *
%輸出字面 %—

二、 標志字符:微調格式

標志效果
-左對齊 (默認右對齊)
+強制顯示正負號
空格正數前加空格,負數顯示負號
#替代形式:o 加 0 前綴;x/X 加 0x/0X;f/e/g 強制保留小數點
0寬度填充用 0 而非空格 (配合寬度使用)

三、 寬度與精度:控制佈局

  • 最小寬度:十進制整數。實際位數超寬則按實際輸出;不足則填充空格 (或配合 0 標志填 0)。
  • 精度:. 開頭 + 十進制整數。
    • 整數類型:最小數字位數,不足前補 0
    • 浮點類型:小數點後位數 (四捨五入)
    • 字符串:最大輸出字符數,超出截斷
  • 動態指定:%*d、%.*s 從參數列表讀取寬度/精度。

四、 長度修飾符:匹配實際類型

修飾符含義典型搭配
hhchar / signed char / unsigned char%hhd, %hhu
hshort / unsigned short%hd, %hu
l (ell)long / unsigned long / double (scanf)%ld, %lf
lllong long / unsigned long long%lld, %llu
Llong double%Lf
zsize_t (C99)%zu
tptrdiff_t (C99)%td
jintmax_t (C99)%jd

關鍵區別:printf 中 %f 和 %lf 等效 (float 自動提升為 double);但 scanf 中 %f 對應 float *,%lf 對應 double *,絕不可混淆。

五、 實戰示例與輸出解讀

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);
// a=15,   15,17,f     (%5d 寬度5,前補3空格)

printf("b=%f,%lf,%5.4lf,%e\n", b, b, b, b);
// b=138.357628,138.357628,138.3576,1.383576e+02
// %5.4lf 寬度5精度4,但整數部分已3位,實際輸出超寬按實際

printf("c=%lf,%f,%8.4lf\n", c, c, c);
// c=35648256.364569,35648256.364569,35648256.3646
// %8.4lf 精度4,四捨五入

printf("d=%c,%8c\n", d, d);
// d=p,       p   (%8c 寬度8,前補7空格)

六、 致命陷阱:參數求值順序與副作用

標準規定:函數參數求值順序未指定 (Unspecified),Turbo C/MSVC 多為右到左,GCC/Clang 可能不同。

int i = 8;
printf("%d %d %d %d %d %d\n", ++i, --i, i--, i++, -i--);

若右到左求值:

  1. -i-- → -8, i=7
  2. i++ → 7, i=8
  3. i-- → 8, i=7
  4. ++i → 8, i=8
  5. --i → 7, i=7
  6. ++i → 8, i=8

輸出順序仍左到右:8 7 8 7 7 8 (視編譯器而定)。

鐵律:同一語句中避免對同一變量進行帶副作用的多次操作。拆分為多條語句,明確順序,保命又可移植。

七、 scanf 進階:掃描集與賦值抑制

  • %*d:讀取整數但不賦值 (跳過)
  • %[^\n]:讀取整行 (含空格) 直到換行符
  • %3c:精確讀取 3 個字符 (不自動加 \0,需手動處理)
  • 空白字符在格式串中匹配任意長度空白 (含換行),%c 除外

八、 最佳實踐清單

  1. 編譯開啟 -Wformat -Wformat-security (GCC/Clang) 捕獲格式字符串漏洞
  2. 優先使用 snprintf、sscanf 防緩衝區溢出
  3. 定長整數類型 (int32_t 等) 配合 <inttypes.h> 的 PRId32 宏,保證跨平台一致
  4. 浮點數高精度輸出用 %.17g (double) 或 %.9g (float) 保證往返無損
  5. 字符串輸入永遠指定寬度:scanf("%255s", buf)

總結

格式符看似瑣碎,實則是 C 語言類型系統與輸出模型的投影。徹底理解各欄位語義、長度修飾符與實際類型的對應、求值順序的不確定性,能讓你寫出既漂亮又安全、可移植的 I/O 代碼。下次見到 %08lld 或 %*.*s,請微笑——你已駕馭它們。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved