了解sscanf用法
更新記錄
item | note |
---|---|
20170308 | 第一版 |
目錄
sscanf.c
- Use scanf with Regular Expressions
The short answer: scanf does not handle regular expressions literally speaking.
有說明若要regular expressions在c,
最好使用(regcomp/regexec)才是有完整支援
在scanf fmt裡面的regular並非完整的
- 由sscanf.c可知道,基本程序如下
sscanf(buf,ftm,)
buf:為輸入字串
fmt:測試格式,將會比對之前,輸出到相應變數1
sscanf("name:john age:40 tel:082-313530","name:%s age:%d tel:%s",name, &age, tel);
程序說明
檢測fmt(即*s) 裡面格式(name:%s age:%d tel:%s)
來比對buf(name:john age:40 tel:082-313530)
設定到name,&age,tel等變數- 若找到%,則開始進入判斷(s c dobxu *)
- 若為*,則表示不取用(即 noassign=1)
- 若為數字(0-9),表示後面重覆幾個(即width)
- 若為s,則表示開始取得想對應字串(依width長度)
- 若為d(base10), x(base16), b(base2)來轉換為數值
若非%
- 若為空格,則往下一個字元 (即buf++)
- 若 s != buf ,則結束,將會回傳轉換的量(即count)
- 若 s == buf ,則下一個字元比對 (即s++,buf++)
sscanf.c
sscanf format
- format字串
C 語言中的 sscanf() 函數1
2
3
4
5
6以%為開始比對,比對成完會設定到後面變數
%[*][width][modifiers]type
% 代表變數開始
* 代表省略不放入變數中
width 代表最大讀取寬度
type 則可以是 c, d,e,E,f,g,G,o, s, u, x, X 等基本型態,也可以是類似 Regular Expression 的表達式。
範例說明
範例來源:使用 sscanf 模仿正規表達式的剖析功能 (作者:陳鍾誠)
sscanf example 1
sscanf(“name:john age:40 tel:082-313530”,”%s”,name);
執行結果,變數內容如下
var | value |
---|---|
name | john |
說明
item | note |
---|---|
%s | 遇到%開始比對,由於沒有設定多少量(width),因此會取到空格為結束 |
sscanf example 2
sscanf(“name:john age:40 tel:082-313530”,”%8s”,name);
執行結果,變數內容如下
var | value |
---|---|
name | name:joh |
說明
item | note |
---|---|
%8s | 遇到%開始比對,width為8,因此strncpy(,,8) |
sscanf example 3
sscanf(“name:john age:40 tel:082-313530”,”%[^:]:%s”,field,name);
執行結果,變數內容如下
var | value |
---|---|
field | name |
name | john |
說明
item | note |
---|---|
%[^:] | 遇到%開始比對,遇到不附合(即不在集合裡面),比對結束,則filed為”name” |
: | 兩邊相同(s,buf),則往下一個字串 |
%s | 遇到%開始比對,取字串(直到空格為止),則name為”john” |
sscanf example 4
sscanf(“name:john age:40 tel:082-313530”,”name:%s age:%d tel:%s”,name, &age, tel);
執行結果,變數內容如下
var | value |
---|---|
name | john |
age | 40 |
tel | 082-313530 |
說明
item | note |
---|---|
name: | 字元相同,往下一個字元比對 |
%s | 遇到%開始比對,取字串(直到空格為止),則name為”john” |
“ age:” | 字元相同,往下一個字元比對 |
%d | 遇到%開始比對,d表非轉換為base10數值,取出字串(直到空格),由atob取得數值,則age為40 |
“ tel:” | 字元相同,往下一個字元比對 |
%s | 遇到%開始比對,取字串(直到空格或buf結束), 則tel為082-313530 |
sscanf example 5
- sscanf(“name:john age:40 tel:082-313530”,”%[^:]:%s %[^:]:%d %*[^:]:%s”,name, &age, tel);
結果為=>john 40 082-313530- sscanf裡面可以使用*在[]裡面,則表示不設定值(即noassign=1)
- 因此後面只要接3個變數
- 注意有幾個%,後面就要接幾個變數,除非有使用*
- 變數型能也要接對(因為都是操作指標,若將int用到%s不會馬上當機
- 但會影響到程式,因為int變數在RAM裡面的下一個變數就會被改到
sscanf example
sscanf example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16sscanf("name:john age:40 tel:082-313530","%s",name);
printf("[0],%s\n",name);
sscanf("name:john age:40 tel:082-313530","%8s",name);
printf("[1],%s\n",name);
sscanf("name:john age:40 tel:082-313530","%[^:]:%s",field,name);
printf("[2],%s %s\n",field,name);
sscanf("name:john age:40 tel:082-313530","name:%s age:%d tel:%s",name, &age, tel);
printf("[3],%s %d %s\n",name,age,tel);
sscanf("name:john age:40 tel:082-313530","%*[^:]:%s %*[^:]:%d %*[^:]:%s",name, &age, tel);
printf("[4],%s %d %s\n",name,age,tel);
char protocol[10], site[50], path[50];
sscanf("http://cckmit.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);test
1
2
3
4
5
6[0],name:john
[1],name:joh
[2],name john
[3],john 40 082-313530
[4],john 40 082-313530
[5],protocol=http site=cckmit.wikidot.com path=cp/list/hello.txt
其它範例
ex1
1
2sscanf("rtsp://10.0.0.141:554/media?profile=h264","%*[^:]:%*2[/]%[^/]/%[a-zA-Z0-9\/+=%&_\.~?\-]", uri_str, streamurl);
printf("%s %s",uri_str,streamurl);執行結果,變數內容如下
var | value |
---|---|
uri_str | 10.0.0.141:554 |
streamurl | media?profile=h264 |
fmt => “rtsp://10.0.0.141:554/media?profile=h264”
item | note |
---|---|
“%*[^:]” | rtsp ,不設定變數 |
“:” | : ,字元相同,往下一個字元比對 |
“%*2[/]” | // ,不設定變數 |
“%[^/]” | “10.0.0.141:554”,將它存到uri_str |
“/“ | / |
“%[a-zA-Z0-9\/+=%&_.~?-]” | media?profile=h264,將它在到streamurl |
正規表示試說明
- 正規表示式 Regular Expression
RegularExpression
[abc] :表示a,b或c
[^abc]:非a,b,c的其它字元sscanf 支持集合操作:
%[a-z] 表示匹配a到z中任意字符,貪婪性(盡可能多的匹配)
%[aB’] 匹配a、B、’中一員,貪婪性
%[^a] 匹配非a的任意字符,貪婪性 =>即表示遇到a則結束