ATS中用到的sscanf高级用法说明
ATS使用sscanf函數主要用來解析配置文件,或者提取出要用到的數據類型的值,比較方便,大家可以使用SourceInsight來搜索sscanf用到的地方,這里補充一些sscanf的知識,方便自己更深入地理解源碼。
正則表達式與sscanf
在c/C++中,如果不想動用pcre這類正則表達式庫,直接可以使sscanf就可以搞定的事情,還是使用sscanf就好。另外,sscanf支持正則表達式,可以完成很多看似無法完成的事情。
基礎知識
名稱:
sscanf() - 從一個字符串中讀進與指定格式相符的數據.
函數原型:
Int? sscanf( string str, string fmt, mixed var1, mixed var2 ... );
int? scanf( const char *format [,argument]... );
說明:
sscanf與scanf類似,都是用于輸入的,只是后者以屏幕(stdin)為輸入源,前者以固定字符串為輸入源。
其中的format可以是一個或多個{%[*] [width] [size]type | ' ' | '\t' | '\n' | 非%符號}
format-type中有%[]這樣的type field。如果讀取的字符串,不是以空格來分隔的話,就可以使用%[]。
%[]類似于一個正則表達式。[a-z]表示讀取a-z的所有字符,[^a-z]表示讀取除a-z以外的所有字符。
注:
1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星號 (*) 表示跳過此數據不讀入. (也就是不把此數據讀入參數中)
2、{a|b|c}表示a,b,c中選一,[d],表示可以有d也可以沒有d。
3、width表示讀取寬度。
4、參數的size: 常用的有hh表示單字節size,h表示2字節 size,其他詳見man sscanf或msdn
5、type :這就很多了,就是%s,%d之類。
6、個人認為正則表達式略顯復雜,還是使用sscanf方便,搞不定再用正則表達式
控制字符說明?
%c ?一個單一的字符?
%d ?一個十進制整數?
%i ?一個整數?
%e, %f, %g 一個浮點數?
%o ?一個八進制數?
%s ?一個字符串?
%x ?一個十六進制數?
%p ?一個指針?
%n ?一個等于讀取字符數量的整數?
%u ?一個無符號整數?
%[] ?一個字符集?
%% ?一個精度符
6、特別的:%*[width] [{h | l | I64 | L}]type 表示滿足該條件的被過濾掉,不會向目標參數中寫入值
%[a-z] 表示匹配a到z中任意字符,貪婪性(盡可能多的匹配)
%[aB'] 匹配a、B、'中一員,貪婪性
%[^a] 匹配非a的任意字符,貪婪性
是不是感覺眼熟了啊,不錯,這和正則表達式很相似,而且仍然支持過濾,即可以有%*[a-z].如: char sztime1[16] = "", sztime2[16] = "";
sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2); sscanf("2006:03:18-2006:04:18", "%[0-9,:]-%[0-9,:]", sztime1, sztime2);
下面是一些功能的演示代碼
//gcc -g sscanf_demo.c -o sscanf_demo
#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main(int argc, char* argv[]){char buf[512] = {0};//1.常見用法,遇到空格就停止sscanf("123456 asdf", "%s", buf);printf("%s\n", buf);//2.獲取指定長度字符串sscanf("123456 asdf", "%4s", buf);printf("%s\n", buf);//3.取得指定字符為止的字符串sscanf("123456 asdf", "%[^ ]", buf);printf("%s\n", buf);//4.僅取指定字符集的字符串sscanf("123456ABCasdf", "%[1-9a-z]", buf);printf("%s\n", buf);sscanf("123456abcdedfBCDEFxyz", "%[^A-Z]", buf);printf("%s\n", buf);//5.獲取指定間隔符之間的字符sscanf("iios/12DDWDFF@12", "%*[^/]/%[^@]", buf);printf("%s\n", buf);sscanf("aaaAAA", "%[a-z]", buf);printf("%s\n", buf);sscanf("AAAaaaBBB", "%[^a-z]", buf);printf("%s\n", buf);sscanf("AAAaaaBBB", "%*[A-Z]%[a-z]", buf);printf("%s\n", buf);memset(buf,'0', sizeof(buf));sscanf("AAAaaaBBB", "%[a-z]", buf);printf("%s\n", buf);sscanf("AAAaaaBC=", "%*[A-Z]%*[a-z]%[^a-z=]", buf);printf("%s\n", buf);int k=0;sscanf("AAA123BBB456", "%*[^0-9]%i", &k);printf("%d\n", k);sscanf("hello, world", "%*s%s", buf);printf("%s\n", buf);char sztime1[16] = {0};char sztime2[16] = {0};sscanf("2006:03:18-2009:04:18", "%[0-9:,]-%[0-9:,]", sztime1, sztime2);printf("[%s], [%s]\n", sztime1, sztime2);sscanf("2006:03:18 - 2009:04:18", "%s - %s", sztime1, sztime2);printf("[%s]||[%s]\n", sztime1, sztime2);//6.指定寬度字符串unsigned char m[6] = {0};int n = 0;n = sscanf("010203040506", "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]);printf("2hhx: %d:%02x%02x%02x%02x%02x%02x\n", n, m[0], m[1], m[2], m[3], m[4],m[5]);//提取日志中的指定字段char pattern[] = "%s -- %s %*[\"]%s %1000[^\"]\" %d %d %*[\"]%1000[^\"]\" %*[\"]%1000[^\"] %*[\"]%s %d";char src[] = "58.56.110.98 -- 1264348800 \"GET http://www.xxxxxxx.cc/web/validate/captcha.php?cid=134&3307 HTTP/1.0\" 404 534 \"-\" \"Trend Micro WTP Add-On 1.2.1046\" TCP_MISS:FIRST_UP_PARENT 13";char ip[16] = {0}, tm[16] = {0}, url[1024] = {0}, cache[32] = {0}, buf1[1000] = {0}, buf2[1000] = {0}, buf3[1000] = {0};int status, len, result;sscanf(src, pattern, ip, tm, url, buf1, &status, &len, buf2, buf3, cache, &result);printf("%s|%s|%s|%s, %d|%d|%d\n", ip, tm, url, cache, status, len, result);//提取url中的指定字段char protocol[8] = {0};int port, chn, type;sscanf("http://192.168.1.253:6500/12/1", "%[^://]%*c%*c%*c%[^:]%*c%d%*c%d%*c%d", protocol, ip, &port, &chn, &type);printf("%s|%s, %d|%d|%d\n", protocol, ip, port, chn, type);//提取人名姓氏char first_name[16] = {0}, last_name[16] = {0};sscanf("Tao\nYunxing", "%[^\n]%*c%s", first_name, last_name);printf("%s %s\n", first_name, last_name);char user_name[32] = {0}, host[16] = {0};sscanf("phil2360@gmail.com", "%[^@]%*c%s", user_name, host);printf("%s || %s\n", user_name, host);return 0;
}
參考文獻
[1].http://www.cnblogs.com/hnrainll/archive/2011/05/05/2037735.html
[2].http://blog.csdn.net/jackyvan/article/details/5349724
[3].http://blog.csdn.net/kenby/article/details/4051018
[4].http://blog.csdn.net/huangxy10/article/details/8117870
總結
以上是生活随笔為你收集整理的ATS中用到的sscanf高级用法说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Ubuntu 14.04 64bit下
- 下一篇: C和C++混合编程的Makefile的编