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

C 語言 sscanf 完整指南:格式化字串解析與掃描集技巧

     編輯:關於C

函式原型與基本說明

int sscanf(const char *str, const char *format, ...);

sscanf 從固定字串讀取格式化資料,類似 scanf 但輸入源為記憶體緩衝區而非標準輸入。回傳成功轉換的參數個數,失敗回傳 EOF(通常為 -1)。

格式字串完整語法

format 可包含一個或多個轉換規格:

%[*][width][{h|l|ll|L}]type
  • *:抑制賦值,跳過該欄位不存入引數(如 %*d、%*s)。
  • width:最大讀取寬度(字元數)。
  • h/l/ll/L:引數大小修飾(h=short, l=long/double, ll=long long, L=long double)。
  • type:轉換類型(d、i、u、x、o、f、e、g、s、c、[...]、p、n 等)。

掃描集(Scanset) —— 類正則的強大功能

%[...] 可定義接受字元集合,支援範圍與排除:

格式含義貪婪性
%[a-z]匹配 a-z 任意字元是(盡可能多)
%[aB']匹配 a、B、' 中任一是
%[^a]匹配非 a 的任意字元是
%[^A-Z]匹配非大寫字母是

注意:%[] 與 %[^] 為非法格式;^ 僅在開頭表示排除。

實戰範例集錦

1. 基本字串讀取

char buf[512] = {0};
sscanf("123456", "%s", buf);        // buf = "123456"
sscanf("123456", "%4s", buf);       // 寬度限制:buf = "1234"

2. 讀取至指定字元為止

sscanf("123456 abcdedf", "%[^ ]", buf);  // 遇到空格停止:buf = "123456"

3. 僅接受指定字元集

sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);  // buf = "123456abcdedf"

4. 讀取至指定字元集為止

sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);  // 遇到大寫停止:buf = "123456abcdedf"

5. 擷取兩個分隔符之間的內容

// 取 / 和 @ 之間:先略過 "iios/",再讀非 @ 字元
sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);  // buf = "12DDWDFF"

6. 解析日期時間格式

int a, b, c;
sscanf("2006:03:18", "%d:%d:%d", &a, &b, &c);  // a=2006, b=3, c=18

char t1[16], t2[16];
sscanf("2006:03:18 - 2006:04:18", "%s - %s", t1, t2);  // t1="2006:03:18", t2="2006:04:18"
// 或更精確:
sscanf("2006:03:18 - 2006:04:18", "%[0-9:] - %[0-9:]", t1, t2);

7. 複雜欄位分隔(以 # 為分隔符)

float price; int qty;
char cat[21], name[21], vendor[21], sku[21];
char buf[201];
fgets(buf, 200, fp);
sscanf(buf, "%20[^#]#%20[^#]#%f#%i#%20[^#]#%20[^\n]",
       name, sku, &price, &qty, cat, vendor);
  • %20[^#]#:最多讀 20 字元,遇 # 停止(不含 #)。
  • %f#、%i#:讀數值後遇 # 停止。
  • %20[^\n]:最多 20 字元,忽略行尾換行。

8. 略過前綴提取數值

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

進階技巧與注意事項

  • 緩衝區大小:搭配寬度限制(如 %20s、%20[^#])防止緩衝區溢位。
  • 回傳值檢查:務必檢查回傳值是否等於預期參數數,確保解析完整。
  • %n 不消耗輸入:記錄截至目前已讀取的字元數,用於後續處理。
  • 非標準擴展:部分實作支援 %ms(自動分配記憶體),屬 GNU 擴展,非標準 C。

總結

sscanf 的強大在於格式字串的表達力,特別是掃描集 %[...] 與抑制賦值 * 的組合,能以極簡潔程式碼完成複雜字串剖析。熟練掌握這些模式,能大幅減少手動字串處理的錯誤與代碼量。

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