c语言sscanf使用正则表达式
来源:互联网 发布:金扎软件 编辑:程序博客网 时间:2024/05/22 05:30
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|I|L} 之一 說明 : 其中 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 <stdio.h>int main() { char name[20], tel[50], field[20], areaCode[20], code[20]; int age; sscanf("name:john age:40 tel:082-313530", "%s", name); printf("%s\n", name); sscanf("name:john age:40 tel:082-313530", "%8s", name); printf("%s\n", name); sscanf("name:john age:40 tel:082-313530", "%[^:]", name); printf("%s\n", name); sscanf("name:john age:40 tel:082-313530", "%[^:]:%s", field, name); printf("%s %s\n", field, name); 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("name:john age:40 tel:082-313530", "%*[^:]:%s %*[^:]:%d %*[^:]:%s", name, &age, tel); printf("%s %d %s\n", name, age, tel); char protocol[10], site[50], path[50]; sscanf("http://ccckmit.wikidot.com/cp/list/hello.txt", "%[^:]:%*2[/]%[^/]/%[a-zA-Z0-9._/-]", protocol, site, path); printf("protocol=%s site=%s path=%s\n", protocol, site, path); return 1;}
其編譯執行結果如下所示。
D:\oc>gcc sscanf.c -o sscanfD:\oc>sscanfname:johnname:johnamename johnjohn 40 082-313530john 40 082-313530protocol=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("http://ccckmit.wikidot.com/cp/list/hello.txt", "%[^:]:%*2[/]%[^/]/%[a-zA-Z0-9._/-]", protocol, site, path); printf("protocol=%s site=%s path=%s\n", protocol, site, path);
- c语言sscanf使用正则表达式
- C语言sscanf函数用法总结(一) 正则表达式
- C语言sscanf函数用法总结(二) 正则表达式
- C语言里sscanf函数的正则表达式
- C语言使用正则表达式
- C语言使用正则表达式
- C语言使用正则表达式
- C语言使用正则表达式
- 在c语言中使用正则表达式
- c语言中使用正则表达式
- C语言使用正则表达式(2)
- C语言中使用正则表达式
- C语言中使用正则表达式
- C语言正则表达式的使用
- c语言中使用正则表达式
- C语言正则表达式使用详解
- C语言中正则表达式如何使用
- 正则表达式和sscanf
- 机器学习 - 贝叶斯理论
- 《机器学习实战》--决策树
- UVa 310 - L--system
- 解决AJAX向后台发送HMTL代码失败的问题
- Ubuntu和windows下共享文件之SSH
- c语言sscanf使用正则表达式
- [leetcode]【数组】26. Remove Duplicates from Sorted Array
- 写论文必看要点
- 冒泡的优化
- 基于FS4412嵌入式系统移植(5) 内核移植
- SDUT1130数据结构上机测试1:顺序表的应用
- redis学习之Jedis使用线程池封装redis的基本操作及spring的简单封装
- 大数的运算
- 263. Ugly Number