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

C 語言 scanf 格式字串進階用法詳解:掃描集與正則風格匹配

     編輯:關於C

核心概念:掃描集

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

進階技巧

1. 解析鍵值對

char s[] = "notepad=1.0.0.1001";
char name[32], ver[32];
sscanf(s, "%[^=]=%s", name, ver); // name="notepad", ver="1.0.0.1001"

2. 忽略特定分隔符

char s[] = "2024-01-15";
int y, m, d;
sscanf(s, "%d-%d-%d", &y, &m, &d); // 直接匹配 '-',極其方便

3. 寬度限制防溢位

char buf[10];
sscanf(input, "%9s", buf); // 最多讀 9 字符 + '\0',安全

返回值與錯誤處理

  • 返回成功匹配並賦值的項目數(可能少於格式數)。
  • 匹配失敗返回 0;EOF 返回 EOF。
  • 注意:fscanf 判斷 EOF 若連續匹配失敗會卡住,建議改用行讀取(fgets)再 sscanf。

常見陷阱與最佳實踐

⚠️ 1. 忽略行首空白

scanf 族會自動跳過格式串中空白字符(含換行),若需精確控制請用 %c 或 fgets。

❌ 2. gets() 已棄用(C11 移除)

緩衝區溢位風險極高,永遠使用 fgets(buf, sizeof(buf), stdin),並自行移除尾隨 \n。

✅ 3. 複雜解析建議

掃描集功能強大但易寫錯、難維護。複雜文本解析建議:fgets 讀整行 → 手寫狀態機或用 strtok_r/正則庫(PCRE/POSIX regex)處理。

完整範例:解析 HTTP 請求行

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 族最強大且最被低估的特性,掌握它能大幅簡化結構化文本解析代碼。但記住:安全第一,複雜場景轉用專用解析器。

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