出处:http://blog.csdn.net/phil2036/archive/2009/05/27/4221704.aspx
在看这篇文章之前建议你先了解一下什么是正则表达式,具体不重复了
好了,具体说说sscanf的这个扩展功能吧(暂且这么叫)。sscanf提供的这个扩展功能其实并不能真正称为正则表达式,因为他的书写还是离不开%,而且也很局限。但是作为处理我上面说的url已经是绰绰有余了。sscanf的这个扩展功能支持[]表示支付范围,{}表示重复次数,^表示取非,*表示跳过。所以上面这个url的解析可以写成下面这个样子:
char url[] = "dv://192.168.1.253:65001/1/1"
sscanf(url,"%[^://]%*c%*c%*c%[^:]%*c%d/%d/%d",protocol,ip,&port,&chn,&type);//这里的参数需要传地址进去。这里面port等整型的声明为int prot...
解释一下
先取得一个最长的字符串,但不包括字串://,于是protocol="dv\0";
然后跳过三个字符(%*c),其实就是跳过://
接着取一个字符串不包括字符串:,于是ip=192.168.1.253,这里简化处理了,IP就当个字符串来弄,而且不做检查
然后跳过冒号取端口到port,再跳过/取通道号到chn,再跳过/取码流类型到type。
是不是觉得还不过瘾?我也觉得,接着举例。
sscanf("Phil\nChang","%[^\n]%*c%s",first_name,last_name);
解释:跳过一个换行符,取first_name和last_name
sscanf("Phil\nChang","%[^\n]%*c%s",str,str1);
//str = Phil str1 = Chang
sscanf("phil2360@gmail.com","%[^@]%*c%s",str,str1);
//str = phil2360 str1 = gmail.com
sscanf("phil2360@gmail.com","%[^@]@%s",str,str1);
//str = phil2360 str1 = gmail.com
基本上,这个东西用的不多,但是有时候很实用,让你的代码会很简洁,但是相比正则表达式,功能又显得简陋很多,怎么用,就看个人而定了,还是那句话,不是很确定这东西是不是ANSI的,所以不考虑移植又觉得很简洁那么用吧,考虑移植那么请三思,至于正则表达式,用regex或者boost库吧,哦,我说的是C++,C#本来就带了的!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/phil2036/archive/2009/05/27/4221704.aspx
以下转自chinaunix:
原文地址:http://blog.chinaunix.net/u/21684/showart_499274.html
头文件 #include(stdio.h)
定义函数 int sscanf (const char *str,const char * format,........);
函数说明 sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。
周星星的代码:
#include<stdio.h>
intmain() { constchar*s="iios/12DDWDFF@122"; charbuf[20];
sscanf(s,"%*[^/]/%[^@]",buf); printf("%s\n",buf);
return0; }
结果为:12DDWDFF
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
|
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性
1.常见用法。
以下是引用片段: charstr[512]={0}; sscanf("123456","%s",str); 2.取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。 以下是引用片段: sscanf("123456","%4s",str); //str = 1234 3.取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。 sscanf("123456abcdedf","%[^ ]",str); //str = 123456abcdedf 4.取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。 sscanf("123456abcdedfBCDEF","%[1-9a-z]",str); //str = 123456abcdedf
5.取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。 sscanf("123456abcdedfBCDEF","%[^A-Z]",str); //str = 123456abcdedf
|
搜集一些特殊用法:
%[]的用法:%[]表示要读入一个字符集合,如果[后面第一个字符是”^”,则表示反意思。
[]内的字符串可以是1或更多字符组成。空字符集(%[])是违反规定的,可导致不可预知的结果。%[^]也是违反规定的。
%[a-z]读取在 a-z 之间的字符串,如果不在此之前则停止,如
chars[]="hello, my friend” ; // 注意: ,逗号在不 a-z之间
sscanf( s, “%[a-z]”, string ) ; // string=hello
%[^a-z] 读取不在 a-z 之间的字符串,如果碰到a-z之间的字符则停止,如
char s[]="HELLOkitty”;// 注意: ,逗号在不 a-z之间
sscanf(s,“%[^a-z]”,string);// string=HELLO
%*[^=]前面带*号表示不保存变量。跳过符合条件的字符串。
chars[]="notepad=1.0.0.1001";
charszfilename[32]="";
inti=sscanf(s,"%*[^=]",szfilename);
// szfilename=NULL,因为没保存
inti=sscanf(s,"%*[^=]=%s",szfilename);
// szfilename=1.0.0.1001
%40c 读取40个字符
%[^=]读取字符串直到碰到’=’号,’^’后面可以带更多字符,如: chars[]="notepad=1.0.0.1001"; charszfilename[32]=""; inti=sscanf(s,"%[^=]",szfilename);
// szfilename=notepad
如果参数格式是:%[^=:],那么也可以从 notepad:1.0.0.1001读取notepad
sscanf( "notepad=1.0.0.1001", "%*[^=]", str );
//str = sscanf( "notepad=1.0.0.1001", "%[^=]", str );
//str = notepad
sscanf( "notepad=1.0.0.1001", "%*[^=]=%s", str );
//str = 1.0.0.1001 sscanf( "notepad=1.0.0.1001", "%*[^=]%s", str );
//str = =1.0.0.1001
|
总结:%[]有很大的功能,但是并不是很常用到,主要因为:
1、许多系统的scanf函数都有漏洞. (典型的就是TC在输入浮点型时有时会出错).
2、用法复杂,容易出错.
3、编译器作语法分析时会很困难,从而影响目标代码的质量和执行效率.
个人觉得第3点最致命,越复杂的功能往往执行效率越低下。而一些简单的字符串分析我们可以自已处理。
参考:
http://blog.csdn.net/beingstudio/articles/1806661.aspx
http://hi.baidu.com/lbird/blog/item/07e09c8282dbe992f703a6b0.html
http://hi.baidu.com/yinjianren/blog/item/28dce5ca75e30585c9176896.html