c語言sscanf使用正規表示式

2021-07-11 23:15:23 字數 3621 閱讀 4496

c 語言中的 scanf 函式,是初學者都會使用的,但也是大部分人都會誤用,或者是無法充分發揮其功能的。

c 語言的 sscanf() 與 ssprintf() 這兩個函式,採用的是一種既創新又好用的設計法,

事實上,函式 sscanf() 比 scanf() 更為好用,sscanf() 甚至支援了類似 regular expression 的功能,可以讓我們輕易的剖析格式化的字串。

sscanf 的函式原形如下,其中的 format 格式字串具有複雜的格式指定功能,以下我們將詳細說明這些格式的用途。

int sscanf ( const

char * str, const

char * format, ...);

str : 被剖析的字串

format: 剖析格式

在 format 字串中,以 % 起頭者為剖析段落,通常在剖析完成後會指定給後面的變數,其格式語法如下:

剖析段落的語法:%[*][width][modifiers]type

% 代表變數開始

* 代表省略不放入變數中

width 代表最大讀取寬度

modifier 可以是 之一

說明 : 其中 h 代表 2 byte 的變數 (像 short

int),

l 代表 4 byte 的變數 (像 long

int),

l 代表 8 byte 的變數 (像 long

double)

type 則可以是 c, d,e,e,f,g,g,o, s, u, x, x 等基本型態,

也可以是類似 regular expression 的表示式。

說明: c : 字元 (char);

d : 整數 (decimal integer);

f : 浮點數 (floating point);

e,e : 科學記號 (scientific notation);

g,g : 取浮點數或科學記號當中短的那個;

o : 八進位 (octal integer);

u : 無號數 (unsigned integer);

x, x : 十六進製 (hexadecimal integer)

為了說明 sscanf 函式的用法,我們寫了以下程式,以示範 format 欄位的各種寫法。

檔案:sscanf.c

#include 

int main()

其編譯執行結果如下所示。

d:\oc>gcc sscanf.c -o sscanf

d:\oc>sscanf

name:john

name:joh

name

name john

john 40 082-313530

john 40 082-313530

protocol=http site=ccckmit.wikidot.com path=cp/list/hello.txt

您應該可以看到,在上述程式碼當中,所有的 %s, %d 等輸入字段,預設都是以空白做為結尾的,例如以下指令就只會掃瞄到name="name:john",因為後面是空白了,所以就把 %s 的內容丟到了變數 name 當中。

sscanf("name:john age:40 tel:082-313530", "%s", name);

printf("%s

\n", name);

如果我們在 %s 等樣式中指定長度,像是以下這個 sscanf 所採用的 %8s,那麼掃瞄到 8 個字元之後就會停止了,所以此時name="name:joh"

sscanf("name:john age:40 tel:082-313530", "%8s", name);

printf("%s

\n", name);

但是我們可以透過類似正規表示式的語法,來設定掃瞄的方式,舉例而言,像是以下的 sscanf 所採用的%[^:],就讓我們 可以掃瞄到:符號為止,其中的樣式[^abc]符號代表不要比對 a, b, c 這些字元,所以[^:]代表的是不可比對到:這個符號,因此就會在比對到該符號時停止了。於是掃瞄的結果會是name="name"

sscanf("name:john age:40 tel:082-313530", "%[^:]", name);

printf("%s

\n", name);

當然、這些 %s, %d 等樣式之間還可以串接,以便進行連續掃瞄,因此下面這個 sscanf 指令可以一次掃出 field 與 name 兩個字段, 結果會是 field="name", name="john" 。

sscanf("name:john age:40 tel:082-313530", "%[^:]:%s", field, name);

printf("%s %s

\n", field, name);

而且、在掃瞄到整數或浮點等非字串欄位時,還會將掃瞄到的結果轉為該型態放入變數中,例如下列 sscanf 指令中的&age字段, 就會直接得到整數值,不需要像一般正規表示式那樣還需要經過轉型才能使用。

sscanf("name:john age:40 tel:082-313530", "name:%s age:%d tel:%s", name, &age, tel);

printf("%s %d %s

\n", name, age, tel);

如果我們希望某些欄位在掃瞄後,直接丟棄而不要存入任何變數中,那麼就可以用%*...這種加上*號的格式,此時 sscanf 會知道要將該字段丟棄,不要存入到後面的變數裡。

sscanf("name:john age:40 tel:082-313530", "%*[^:]:%s %*[^:]:%d %*[^:]:%s", name, &age, tel);

printf("%s %d %s

\n", name, age, tel);

甚至、我們可以真的把 sscanf 當成「正規表示式」使用,只是語法稍有差異,功能也不像正規表示式那麼強,不過通常也夠用了。

舉例而言,以下的 sscanf 可以將乙個網址剖析成 protocol, site, path 等三個段落,您可以看到我們使用的"%[^:]:%*2[/]%[^/]/%[a-za-z0-9._/-]"這個樣式,看起來是不是真的很像「正規表示式」呢?

char protocol[10], site[50], path[50];

sscanf("",

"%[^:]:%*2[/]%[^/]/%[a-za-z0-9._/-]",

protocol, site, path);

printf("protocol=%s site=%s path=%s

\n", protocol, site, path);

sscanf正規表示式

c語言 sscanf正規表示式 2011 01 07 00 18 表頭檔案 include stdio.h 定義函式 int sscanf const char str,const char format,函式說明 sscanf 會將引數str的字串根據引數format字串來轉換並格式化資料。格式轉...

sscanf與正規表示式

from 今天翻google reader的時候看到這樣一篇文章,介紹的是sscanf的高階用法。直到今天我才知道sscanf是可以直接用正規表示式的,慚愧。在msdn中sscanf的宣告如下 int sscanf const char buffer const char format argume...

sscanf正規表示式 二

表頭檔案 include stdio.h 定義函式 int sscanf const char str,const char format,函式說明 sscanf 會將引數str的字串根據引數format字串來轉換並格式化資料。格式轉換形式請參考scanf 轉換後的結果存於對應的引數內。返回值 成功...