printf或者sprintf必定是任何一個C程序員最多見到的函數,與sprintf的做用相反,sscanf一般被用來解析並轉換字符串,其格式定義靈活多變,能夠實現很強大的字符串解析功能。程序員
sscanf的原型很簡單,定義以下:正則表達式
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
函數
str:待解析的字符串工具
format:字符串格式描述,其後是一序列數目不定的指針參數,存儲解析後的數據url
下面是一個簡單的例子:.net
int year, month, day;指針
int converted = sscanf("20080808", "%04d%02d%02d", &year, &month, &day);orm
printf("converted=%d, year=%d, month=%d, day=%d/n", converted, year, month, day);blog
輸出結果:
converted=3, year=2008, month=8, day=8
"%04d%02d%02d"是用來解析字符串的格式,%表示格式轉換的開始,d表示轉換爲一個整數,04做爲d的修飾,表示這是一個長度爲4位的整數,不足4位時以0補齊。
例子返回結果等於3,表示有3個數據成功轉換,轉換成功數目同時取決於被解析的字符串以及其轉換格式,若是咱們把例子中的格式改成"%04d%02d",那麼sscanf將只返回2,day的數值不會被sscanf更改。
這是一個浮點數轉換的例子:
double longitude, latitude;
int converted = sscanf("113.123456789 31.123456789", "%lf %lf", &longitude, &latitude);
printf("converted=%d, longitude=%.9lf, latitude=%lf/n", converted, longitude, latitude);
輸出結果:
converted=2, longitude=113.123456789, latitude=31.123457
sscanf的格式字符串中,f表示這是一個浮點數,其修飾詞l表示這是一個double的浮點數。
上面是兩個關於sscanf基本的例子,下面咱們來演示sscanf的高級用法:
char str[32] = "";
sscanf("123456abcdedf", "%31[0-9]", str);
printf("str=%s/n", str);
輸出結果:
str=123456
上面的格式中,[0-9]表示這是一個僅包含0-9這幾個字符的字符串,前面使用數字31修飾詞表示這個字符串緩衝區的最大長度(這也是sscanf最爲人詬病的地方,很容易出現緩衝區溢出錯誤,實際上sscanf是能夠避免出現緩衝區溢出的,只要在書寫任何字符串解析的格式時,注意加上其緩衝區尺寸的限制)。
又一個例子:
char str[32] = "";
sscanf("123456abcdedf", "%31[0-9a-z]", str);
printf("str=%s/n", str);
輸出結果:
str=123456abcdedf
在格式[]中增長了a-z的描述。
使用^的例子:
char str[32] = "";
sscanf("123456abcdedf", "%31[^a-z]", str);
printf("str=%s/n", str);
輸出結果:
str=123456
在[]中增長^表示相反的意思,上面的[^a-z]表示一個不包含任何a-z之間的字符串。
使用*的例子:
char str[32] = "";
int ret = sscanf("123456abcdedf", "%*[0-9]%31[a-z]", str);
printf("ret=%d, str=%s/n",ret, str);
輸出結果:
ret=1, str=abcdedf
加上*修飾表示一個被忽略的數據,同時也不須要爲它準備空間存放解析結果。如上面的例子中,咱們就只使用了str一個參數存放%31[a-z]的解析結果,而sscanf也只返回1,表示只解析了一個數據。
掌握了[], ^, *如何使用後,咱們會發現sscanf原來是一個如此強大的工具,不少咱們原先認爲必須使用正則表達式的地方,極可能使用sscanf就能夠實現。
下面是format的一些參考資料:
轉換類型:
%d:整數,須要一個類型爲int*的的參數存放轉換結果
%i:整數,若是字符串以0x或者0X開頭,則按16進制進行轉換,若是以0開頭,則按8進制進行轉換,不然按10進制轉換,須要一個類型爲int*的的參數存放轉換結果
%o:無符號的8進制數,須要一個類型爲unsigned int*的參數存放轉換結果
%u:無符號的整數,須要一個類型爲unsigned int*的參數存放轉換結果
%x:無符號的16進制數,須要一個類型爲unsigned int*的參數存放轉換結果
%X:等同於%x
%f:浮點數,須要一個類型爲float*的參數存放轉換結果
%c:單個字符,須要一個類型爲char*的參數存放轉換結果
%s:以空格或者換行符結尾的字符串,須要一個類型爲char*的參數存放轉換結果
%[]:僅包含在[]中的字符的字符串,如[0-9]表示一個所有是數字的字符串,[a-z]表示一個所有爲小寫字母的字符串,須要一個類型爲char*的參數存放轉換結果
%[^]:與上面相反,[^以後,]以前的全部字符都做爲字符串結束標誌,如[^0-9]表示一個不包含任何0-9的字符串,須要一個類型爲char*的參數存放轉換結果
轉換類型修飾符:
*:忽略標誌,如%*d表示忽略一個整數,%*s表示忽略一個字符串
h:short修飾符,如%hd表示這是一個short int的整數
l:long修飾符,如%ld表示這是一個long int的整數, %lf表示這是一個double的浮點數(%f表示一個float的浮點數)
L: <GCC> long long修飾符,如%Ld表示這是一個64位字節的整數, %Lf表示這是一個long double的浮點數
I64: <VisualC++> __int64修飾符,如%I64d表示這是一個64位字節的整數