| 組成 | 說明 | 範例 |
| 格式說明 | 以 % 開頭,指定輸入資料型態、寬度等 | %d, %f, %c, %s, %lf |
| 普通字元 | 原樣比對輸入流中對應字元(用於跳過分隔符) | 空格, 逗號, 換行符 |
輸入項列表關鍵規則
- 必須為變數位址:變數名前加
&(位址運算子)
scanf("%d", &a); ✓ 正確
scanf("%d", a); ✗ 錯誤(傳值而非位址)
- 多變數以逗號分隔:
scanf("%d%f", &a, &b);
- 輸入型態須與變數型態一致:
%d 對 int、%f 對 float、%lf 對 double
格式說明完整語法
% [*] [寬度] [長度修飾符] 格式字元
| 元素 | 說明 | 範例 |
| * | 指派抑制:讀取但不存入變數(跳過) | %*d 跳過一整數 |
| 寬度 | 最大讀取字元數 | %5d 讀最多 5 位數字 |
| 長度修飾符 | h=short, l=long/double, L=long double | %hd, %ld, %lf, %Lf |
| 格式字元 | 指定資料型態 | d, i, o, u, x, f, e, g, c, s, p, n |
常用格式字元對照表
| 格式字元 | 對應型態 | 輸入格式 |
| %d, %i | int * | 十進位整數(%i 兼支援八/十六進位前綴) |
| %o | int * | 八進位整數 |
| %u | unsigned int * | 無號十進位整數 |
| %x, %X | int * | 十六進位整數 |
| %f, %e, %g | float * | 浮點數(含科學標記法) |
| %lf | double * | 雙精度浮點數 |
| %c | char * | 單一字元(含空白字元) |
| %s | char * | 字串(遇空白結束) |
| %p | void ** | 指標位址 |
| %n | int * | 已讀取字元數存入變數 |
普通字元在控制字串中的作用
用於比對並跳過輸入流中固定格式分隔符。
scanf("%d,%d", &a, &b); // 輸入必須為 "10,20" 格式,逗號被比對消耗
scanf("%d %d", &a, &b); // 空格比對任意數量空白字元(空格、Tab、換行)
scanf 進階技巧與常見坑
1. 空白字元處理差異
%d、%f、%s:自動跳過前導空白(空格、Tab、換行)
%c:不跳過空白,直接讀取下一字元(含空格、換行)
%[...] 掃描集:不跳過空白,依字元集合讀取
2. 緩衝區殘留換行符問題
int a; char c;
scanf("%d", &a); // 輸入 "10\n",a=10,\n 殘留緩衝區
scanf("%c", &c); // 直接讀取殘留 \n,c='\n' 而非預期字元
解決方案
scanf(" %c", &c); — 格式字串前加空格,跳過空白
getchar(); — 呼叫前清除一字元
while(getchar()!='\n'); — 清空整行
3. 緩衝區溢位風險
char str[10];
scanf("%s", str); // 輸入超過 9 字元會溢位
安全寫法
scanf("%9s", str); — 限制寬度(留 1 給 \0)
fgets(str, sizeof(str), stdin); — 推薦,自動處理邊界與換行
4. 回傳值檢查
if (scanf("%d", &a) != 1) {
// 輸入非整數或 EOF,處理錯誤
while (getchar() != '\n'); // 清理緩衝區
}
getchar / putchar 單字元 I/O
| 函數 | 原型 | 功能 | 典型用途 |
| getchar | int getchar(void) | 讀取一字元,回傳字元值或 EOF | 逐字元處理、清理緩衝區 |
| putchar | int putchar(int c) | 輸出一字元,回傳字元值或 EOF | 單字元輸出、效率優於 printf |
範例:統計輸入行字元數
int n = 0;
while (getchar() != '\n') n++;
printf("%d", n);
完整範例:混合型態輸入
#include
int main() {
int age; float height; char gender; char name[20];
printf("輸入姓名 年齡 性別 身高 (如: John 25 M 175.5): ");
// %19s 防溢位,空格分隔自動跳過空白
if (scanf("%19s %d %c %f", name, &age, &gender, &height) == 4) {
printf("姓名:%s 年齡:%d 性別:%c 身高:%.1f\n", name, age, gender, height);
} else {
printf("輸入格式錯誤\n");
}
return 0;
}
關鍵總結
scanf 控制字串含格式說明(%...)與普通字元(比對跳過)
- 輸入項必須傳變數位址 (&var) — 初學者最常見錯誤
- 格式字元與變數型態嚴格對應(
%lf 對 double、%f 對 float)
%c 不跳空白,%s 遇空白停止,%[...] 掃描集進階用法
- 輸入緩衝區殘留換行符需主動清理
- 永遠限制 %s 寬度或用
fgets 防緩衝區溢位
- 檢查 scanf 回傳值確認成功讀取項目數
- 上一篇文章: C語言函數設計原則:參數傳遞、效率優化與內聯代碼權衡
- 下一篇文章: C語言條件控制語句詳解:if-else 分支結構與複合語句應用
Copyright ©
程式碼之家 All Rights Reserved