在C語言應用開發過程中,常常需要對字串數據進行解析,這些字串可能是從檔案、鍵盤或者其他裝置讀入。比如與 AT 裝置通訊時,需要對 AT 裝置發送過來的數據進行解析,從而獲得我們想要的一些數據。
然而,處理字串卻是一件很麻煩的事!幸運的是,我們有 sscanf() 函數。sscanf 可以認爲是標準 C 庫自帶的 split string (字串分割)函數,它強大的功能體現在對 format 的支援上。
在 stdio.h 中,提供了三個類似的函數,函數原型如下:
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
其中,scanf() 從標準輸入 stdin(鍵盤)中讀進與指定格式相符的數據,fscanf() 從檔案流中讀進與指定格式相符的數據,sscanf() 從一個字串中讀進與指定格式相符的數據。而後面 format 參數格式是一樣的。
format 說明符形式爲:[=%[*][width][modifiers]type=]
參數 | 描述 |
---|---|
* |
這是一個可選的星號,表示數據是從流 stream 中讀取的,但是可以被忽視,即它不儲存在對應的參數中。 |
width |
這指定了在當前讀取操作中讀取的最大字元數。 |
modifiers |
爲對應的附加參數所指向的數據指定一個不同於整型(針對 d、i 和 n)、無符號整型(針對 o、u 和 x)或浮點型(針對 e、f 和 g)的大小: h :短整型(針對 d、i 和 n),或無符號短整型(針對 o、u 和 x) l :長整型(針對 d、i 和 n),或無符號長整型(針對 o、u 和 x),或雙精度型(針對 e、f 和 g) L :長雙精度型(針對 e、f 和 g) |
type |
一個字元,指定了要被讀取的數據型別以及數據讀取方式。也就是 %c 、%d 、%e 、%f 、%o 、%s 、%u 、%x 之類的。 |
對於 %s
字串匹配,sscanf 預設使用空格進行分割,如果希望以其他字元進行分割,可以使用 %[]
形式。比如:
%[a-z]
表示匹配 a
到 z
中任意字元,貪婪性(儘可能多的匹配)%[aB']
匹配 a
、B
、'
中一員,貪婪性%[^a]
匹配非 a 的任意字元,貪婪性1、常見用法。
char buf[512] = ;
sscanf("123456 ", "%s", buf);
printf("%s\n", buf);
結果爲:123456
2、取指定長度的字串。如在下例中,取最大長度爲4位元組的字串。
sscanf("123456 ", "%4s", buf);
printf("%s\n", buf);
結果爲:1234
3、取到指定字元爲止的字串。如在下例中,取遇到空格爲止字串。
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
結果爲:123456
4、取僅包含指定字元集的字串。如在下例中,取僅包含1到9和小寫字母的字串。
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
printf("%s\n", buf);
結果爲:123456abcdedf
5、取到指定字元集爲止的字串。如在下例中,取遇到大寫字母爲止的字串。
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
printf("%s\n", buf);
結果爲:123456abcdedf
6、給定一個字串iios/12DDWDFF@122,獲取 / 和 @ 之間的字串,先將 "iios/"過濾掉,再將非’@'的一串內容送到buf中
sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
printf("%s\n", buf);
結果爲:12DDWDFF
7、給定一個字串「「hello, world」,僅保留 world。(注意:「,」之後有一空格)
sscanf(「hello, world」, "%*s%s", buf);
printf("%s\n", buf);
結果爲:world
注意:%*s
表示第一個匹配到的 %s
被過濾掉,即 hello 被過濾了,如果沒有空格則結果爲 NULL。
sscanf 的功能很類似於正則表達式,但卻沒有正則表達式強大,所以如果對於比較複雜的字串處理,建議使用正則表達式。