scanf 族函數(scanf、fscanf、sscanf)支援 掃描集 語法 %[...],可實現類正則的字符級模式匹配,遠超 %s 僅能讀單詞的限制。
| 格式 | 含義 | 範例輸入 → 結果 |
|---|---|---|
%[a-z] | 讀取連續小寫字母 | "hello, world" → "hello"(遇逗號停止) |
%[^a-z] | 讀取非小寫字母 | "HELLOkitty" → "HELLO"(遇 k 停止) |
%[^=] | 讀取直到 '=' 為止 | "notepad=1.0" → "notepad" |
%*[^=]=%s | 跳過 '=' 前內容,讀取後續 | "notepad=1.0" → "1.0" |
%40c | 固定讀 40 字符(含空白) | 需手動結束,不自動加 \0 |
char s[] = "notepad=1.0.0.1001";
char name[32], ver[32];
sscanf(s, "%[^=]=%s", name, ver); // name="notepad", ver="1.0.0.1001"
char s[] = "2024-01-15";
int y, m, d;
sscanf(s, "%d-%d-%d", &y, &m, &d); // 直接匹配 '-',極其方便
char buf[10];
sscanf(input, "%9s", buf); // 最多讀 9 字符 + '\0',安全
0;EOF 返回 EOF。fscanf 判斷 EOF 若連續匹配失敗會卡住,建議改用行讀取(fgets)再 sscanf。scanf 族會自動跳過格式串中空白字符(含換行),若需精確控制請用 %c 或 fgets。
gets() 已棄用(C11 移除)緩衝區溢位風險極高,永遠使用 fgets(buf, sizeof(buf), stdin),並自行移除尾隨 \n。
掃描集功能強大但易寫錯、難維護。複雜文本解析建議:fgets 讀整行 → 手寫狀態機或用 strtok_r/正則庫(PCRE/POSIX regex)處理。
char line[] = "GET /index.html HTTP/1.1";
char method[8], path[256], version[16];
if (sscanf(line, "%7s %255s %15s", method, path, version) == 3) {
printf("Method=%s Path=%s Ver=%s\n", method, path, version);
}
%[...] 掃描集是 scanf 族最強大且最被低估的特性,掌握它能大幅簡化結構化文本解析代碼。但記住:安全第一,複雜場景轉用專用解析器。