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

C 語言 printf 與 scanf 格式化輸入輸出深度解析

     編輯:關於C語言

printf 函數核心機制

參數傳遞與堆疊模型

printf 採用可變參數機制,參數按順序壓入堆疊。關鍵在於:編譯器按實際類型壓棧,但 printf 按格式字串解讀。

printf("%ld %ld %ld %ld", n1, n2, n3, n4);
// 假設 n1=float, n2=double, n3=n4=long
  • float 自動提升為 double(佔 8 位元組)
  • double 佔 8 位元組
  • long 佔 4 位元組
  • printf 看到四個 %ld,每次讀 4 位元組 → 讀取錯誤位元組組合

教訓:格式字串必須與實際參數類型嚴格匹配,否則產生未定義行為。

返回值與實戰範例

printf 返回成功輸出的字符數,錯誤返回負數。

int a = 100;
printf("a=%d\n", a);      // a=100
printf("a=%5d\n", a);     // a=  100 (寬度5,右對齊)
printf("a=%-5d\n", a);    // a=100   (左對齊)
printf("a=%+d\n", a);     // a=+100  (顯示正號)
printf("a=% d\n", a);     // a= 100  (正數前留空格)
printf("a=%#o\n", a);     // a=0144  (八進制加前綴)
printf("a=%#x\n", a);     // a=0x64  (十六進制加前綴)

最小寬度與填充規則

  • %3d:最小寬度 3,不足左填空格
  • %-3d:左對齊,右填空格
  • %03d:右對齊,左填 0
  • %-03d:0 標誌被 - 覆蓋,左對齊

scanf 函數深度解析

輸入分割與匹配規則

  • 以空白字符(空格、換行、製表符)分割輸入欄位
  • 跳過格式字串與輸入欄位間的空白字符
  • %c 例外:不跳過空白,直接讀取下一字符(含空白)

掃描流程詳解(以 %d 為例)

  1. 跳過前導空白字符
  2. 遇到非空白字符:若為數字或 +/- 符號,繼續讀取數字
  3. 遇到非數字字符:停止掃描,將該字符退回輸入緩衝區
  4. 計算數值賦給目標變數

若首個非空白字符非數字(如 'A'),scanf 停留在該字符,不賦值,返回 0。後續調用仍從 'A' 開始。

%s 與 %c 的關鍵差異

格式讀取內容停止條件空白處理
%s單詞(非空白序列)空白或寬度限制跳過前導空白
%c單一字符讀取 1 字符(或指定寬度)不跳過,含空白

%s 自動在末尾添加 '\0' 形成 C 字串。

返回值語義

  • 成功讀取的項目數
  • 0:無項目讀取(如預期數字輸入字母)
  • EOF(通常 -1):檢測到檔案結尾

常見坑點總結

  • 格式字串與參數類型不匹配:導致堆疊讀取錯亂
  • scanf 留下換行符:後續 %c 直接讀到換行,需用 getchar() 清理或改用 %*c
  • 緩衝區溢出風險:%s 無長度限制,建議用 %19s(緩衝區大小-1)
  • 指針參數:scanf 所有參數必須是地址(&變數或陣列名)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved