| 規則 | 說明 | 正確範例 | 錯誤範例 |
| 參數必須是**位址** | 需用 & 取址(陣列名/指標已是位址) | scanf("%d", &n); | scanf("%d", n); |
| 非格式字元需原樣匹配 | 格式串中的逗號、冒號等必須在輸入中出現 | scanf("%d,%d", &a, &b); 輸入 1,2 | 輸入 1 2 失敗 |
| 空白字元可匹配任意空白序列 | 格式串中空白/換行/Tab 等價 | scanf("%d %d", &a, &b); 輸入 1\n2 成功 | |
%c 不跳過空白 | 讀取下一個字元(含空白),若需跳過前導空白用 %c | scanf(" %c", &c); | scanf("%c", &c); 讀到換行 |
%s 遇空白停止 | 讀取單詞,自動補 \0,需預留緩衝區大小 | scanf("%19s", buf); 防溢位 | scanf("%s", buf); 危險 |
| 浮點無精度控制 | %5.2f 非法,寬度僅限字元數 | | |
完整範例
#include <stdio.h>
int main() {
int a, b; long c; float f; double d; char ch, str[20];
printf("輸入兩整數(空白分隔):");
scanf("%d %d", &a, &b);
printf("輸入長整數:");
scanf("%ld", &c);
printf("輸入浮點數:");
scanf("%f %lf", &f, &d);
printf("輸入字元(跳過空白):");
scanf(" %c", &ch); // 前導空白跳過換行
printf("輸入字串(無空白):");
scanf("%19s", str); // 寬度 19 留 1 給 \0
printf("結果:a=%d b=%d c=%ld f=%.2f d=%.2f ch=%c str=%s\n",
a, b, c, f, d, ch, str);
return 0;
}
掃描集 %[...] 進階用法
char line[100];
scanf("%[^\n]", line); // 讀取整行(含空白),遇 \n 停止
scanf("%[a-zA-Z]", str); // 僅讀取字母
scanf("%[^,]", field); // 讀到逗號為止(CSV 解析)
錯誤處理模式
int n;
if (scanf("%d", &n) != 1) {
// 輸入非整數或 EOF
scanf("%*[^\n]"); // 清除當行殘留
scanf("%*c"); // 吞掉 \n
}
總結
scanf 型別不安全、緩衝區溢位風險高、錯誤處理繁瑣。
- **現代 C++ 強烈建議改用
std::cin / std::getline / std::stringstream**。
- 若必須用 C:嚴格檢查回傳值、限制字串寬度、清理輸入緩衝區、區分
%c 與 %c。
- 上一篇文章: C 語言 volatile 關鍵字深度解析
- 下一篇文章: C/C++ return 語句與 main 函數回傳值規範
Copyright ©
程式碼之家 All Rights Reserved