function <cstdio> sscanf int sscanf ( const char * s, const char * format, ...); Read formatted data from string Reads data from s and stores them according to parameter format into the locations given by the additional arguments, as if scanf was used, but reading from s instead of the standard input (stdin). The additional arguments should point to already allocated objects of the type specified by their corresponding format specifier within the format string. Parameters s C string that the function processes as its source to retrieve the data. format C string that contains a format string that follows the same specifications as format in scanf (see scanf for details). ... (additional arguments) Depending on the format string, the function may expect a sequence of additional arguments, each containing a pointer to allocated storage where the interpretation of the extracted characters is stored with the appropriate type. There should be at least as many of these arguments as the number of values stored by the format specifiers. Additional arguments are ignored by the function. Return Value On success, the function returns the number of items in the argument list successfully filled. This count can match the expected number of items or be less (even zero) in the case of a matching failure. In the case of an input failure before any data could be successfully interpreted, EOF is returned.
頭文件
返回值
sscanf與scanf類似,都是用於輸入的,只是后者以鍵盤(stdin)為輸入源,前者以固定字符串為輸入源。
格式控制符,類似於正則表達式:
支持集合操作
例子
1
2
3
|
char
buf[512];
sscanf
(
"123456"
,
"%s"
,buf);
//此處buf是數組名,它的意思是將123456以%s的形式存入buf中!
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(
"123456"
,
"%4s"
,buf);
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(
"123456abcdedf"
,
"%[^a-z]"
,buf);
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(
"123456abcdedfBCDEF"
,
"%[1-9a-z]"
,buf);
printf
(
"%s\n"
,buf);
|
1
|
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(
"123456abcdedfBCDEF"
,
"%[^A-Z]"
,buf);
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(
"iios/12DDWDFF@122"
,
"%*[^/]/%[^@]"
,buf);
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(“hello, world”,
"%*s%s"
,buf);
printf
(
"%s\n"
,buf);
|
1
2
|
sscanf
(“字符串1\t字符串2\t字符串3”,
"%s%s%s"
,str1,str2,str3);
printf
(
"%s\t%s\t%s\n"
,str1,str2,str3);
|
sscanf及sscanf_s的常用方法,原來安全版本的函數,對參數和緩沖邊界做了檢查,增加了返回值和拋出異常。這樣增加了函數的安全性,減少了出錯的幾率。
同時這也意味着在使用這些函數時,有時你不得不輸入更多的關於緩沖區大小的參數,多敲幾下鍵盤能換來更少的麻煩,值得!
下面總結了sscanf的以及sscanf_s的常用方法,也體現了“_s”版本函數與原函數的特別之處:
1、sscanf和scanf的不同是輸入來源,前者是一個字符串,后者則是標准輸入設備
2、sscanf的使用,以解析時間字符串為例,將字符串“2009-01-02_11:12:13”解析為整型年月日時分秒
//定義
char cc;
tm tm_temp={0};
string stime("2009-01-02_11:12:13");
(1) 必須嚴格按照分隔符形式匹配填寫,若遇到不匹配項則終止解析
sscanf(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",
&tm_temp.tm_year,
&tm_temp.tm_mon,
&tm_temp.tm_mday,
&tm_temp.tm_hour,
&tm_temp.tm_min,
&tm_temp.tm_sec
);
(2) 可以不按照分割符號形式填寫,字符數必須一致,例如可以正確解析“2009/01/02_11:12:13”
sscanf(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",
&tm_temp.tm_year, &cc,
&tm_temp.tm_mon, &cc,
&tm_temp.tm_mday, &cc,
&tm_temp.tm_hour, &cc,
&tm_temp.tm_min, &cc,
&tm_temp.tm_sec
);
(3) 可以不按照分割符號形式填寫,字符數必須一致,同上,%1s可以等同於%c
sscanf(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",
&tm_temp.tm_year, &cc,
&tm_temp.tm_mon, &cc,
&tm_temp.tm_mday, &cc,
&tm_temp.tm_hour, &cc,
&tm_temp.tm_min, &cc,
&tm_temp.tm_sec
);
(4) 可以不按照分割符形式和數量填寫,類型必須一致,例如可以正確解析“2009/01/02___11:12:13”
這里使用了sscanf的正則表達式,與通用的正則表示類似但不完全相同,%*c表示忽略連續多個字符
sscanf(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",
&tm_temp.tm_year,
&tm_temp.tm_mon,
&tm_temp.tm_mday,
&tm_temp.tm_hour,
&tm_temp.tm_min,
&tm_temp.tm_sec
);
3、sscanf_s的使用
//定義
char cc[2];
tm tm_temp={0};
string stime("2009-01-02_11:12:13");
(1) 與sscanf第一種方法相同,可以使用"%4d-%2d-%2d_%2d:%2d:%2d"格式匹配解析
sscanf_s(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",
&tm_temp.tm_year,
&tm_temp.tm_mon,
&tm_temp.tm_mday,
&tm_temp.tm_hour,
&tm_temp.tm_min,
&tm_temp.tm_sec
);
(2) 使用%c格式對數據解析時,必須對相應的緩沖區增加長度參數,否則將會出錯
sscanf_s(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",
&tm_temp.tm_year, &cc, 1,
&tm_temp.tm_mon, &cc, 1,
&tm_temp.tm_mday, &cc, 1,
&tm_temp.tm_hour, &cc, 1,
&tm_temp.tm_min, &cc, 1,
&tm_temp.tm_sec
);
(3) 使用%s格式對數據解析時,緩沖長度必須大於字符串長度,否則不予解析
sscanf_s(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",
&tm_temp.tm_year, &cc, 2,
&tm_temp.tm_mon, &cc, 2,
&tm_temp.tm_mday, &cc, 2,
&tm_temp.tm_hour, &cc, 2,
&tm_temp.tm_min, &cc, 2,
&tm_temp.tm_sec
);
(4) 與sscanf一樣,sscanf_s同樣支持正則表達式
sscanf_s(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",
&tm_temp.tm_year,
&tm_temp.tm_mon,
&tm_temp.tm_mday,
&tm_temp.tm_hour,
&tm_temp.tm_min,
&tm_temp.tm_sec
);
通過以上對比sscanf與sscanf_s的使用,可以看出后者對緩沖區安全有了更多的考慮,從而避免了許多不經意的煩惱。
大家都知道sscanf是一個很好用的函數,利用它可以從字符串中取出整數、浮點數和字符串等等。它的使用方法簡單,特別對於整數和浮點數來說。但新手可 能並不知道處理字符串時的一些高級用法,這里做個簡要說明吧。
#include <stdio.h>
#include <string.h>
int main() {
char input[] = "{\"Vesion\":1.0,\"cmd\":\"live\",\"data\":{\"action\":\"play\",\"params\" : [{\"type\":\"video1\",\"media_ip\":\"192.168.89.4\",\"channel\":1}]}}";
char ip[16];
int stream;
char *pstr = strstr(input, "media_ip");
printf("pstr=%s\n",pstr+11);
int ret=sscanf(strstr(input,"media_ip")+11, "%[0-9.]%*[^:]:%d[0-9]",ip,&stream); // 這里必須是取地址
printf("ret=%d,ip=%s,stream=%d\n",ret,ip,stream);
printf("Over");
getchar();
return 0;
}