在softmse (Jake) 的问题贴http://community.csdn.net/Expert/topic/4843/4843294.xml?temp=.4321558 中 ,周星星给出了一个很cool的sscanf用例,而后通过学习,发现sscanf真棒,现做一总结。
原问题:
iios/12DDWDFF@122
获取/和@之间的字符串怎么做
C程序里面有什么函数吗?
周星星的代码:
#include <stdio.h>
int main()
{
const char* s = "iios/12DDWDFF@122 ";
char buf[20];
sscanf( s, "%*[^/]/%[^@]", buf );
printf( "%s/n", buf );
return 0;
}
结果为:12DDWDFF
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
函数原型:
int scanf( const char *format [,argument]... );
其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '/t' | '/n' | 非%符号},
注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
width:宽度,一般可以忽略,用法如:
const char sourceStr[] = "hello, world";
char buf[10] = {0};
sscanf(sourceStr, "%5s", buf); //%5s,只取5个字符
cout << buf<< endl;
结果为:hello
{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
type :这就很多了,就是%s,%d之类。
特别的:
%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值。如:
const char sourceStr[] = "hello, world";
char buf[10] = {0};
sscanf(sourceStr, "%*s%s", buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
cout << buf<< endl;
结果为:world
支持集合操作:
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性
是不是感觉眼熟了啊,不错,这和正则表达式很相似,而且仍然支持过滤,即可以有%*[a-z].如:
星星大哥例子回顾:
const char* s = "iios/12DDWDFF@122 ";
char buf[20];
sscanf( s, "%*[^/]/%[^@]", buf );
printf( "%s/n", buf );
先将 "iios/"过滤掉,再将非'@' 的一串内容送到buf中,cool.得到结果。
//"%*[^/]匹配(非/)并过滤掉,但并不终止。+ / 也将/过滤掉,
非'@' 的一串也将过滤掉。
PS: 向星星大哥和softmse (Jake) 致谢了,有了你们才有它啊