sscanf函数⽤法详解
sscanf函数⽤法详解
⾸先应该注意的是 sscanf()只能对字符数组进⾏操作,但是不能对string字符串操作
  名称:
  sscanf() - 从⼀个字符串中读进与指定格式相符的数据.
  函数原型:
  Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
  int scanf( const char *format [,argument]... );
  说明:
  sscanf与scanf类似,都是⽤于输⼊的,只是后者以屏幕(stdin)为输⼊源,前者以固定字符串为输⼊源。
  其中的format可以是⼀个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | ⾮%符号}
  注:
  1、 * 亦可⽤于格式中, (即 %*d 和 %*s) 加了星号 (*) 表⽰跳过此数据不读⼊. (也就是不把此数据读⼊参数中)
  2、{a|b|c}表⽰a,b,c中选⼀,[d],表⽰可以有d也可以没有d。
  3、width表⽰读取宽度。
  4、{h | l | I64 | L}:参数的size,通常h表⽰单字节size,I表⽰2字节 size,L表⽰4字节size(double例外),l64表⽰8字节size。
  5、type :这就很多了,就是%s,%d之类。
  6、特别的:%*[width] [{h | l | I64 | L}]type 表⽰满⾜该条件的被过滤掉,不会向⽬标参数中写⼊值
  ⽀持集合操作:
  %[a-z] 表⽰匹配a到z中任意字符,贪婪性(尽可能多的匹配)
  %[aB'] 匹配a、B、'中⼀员,贪婪性
  %[^a] 匹配⾮a的任意字符,贪婪性
例⼦:
  1. 常见⽤法。
  char buf[512] = ;
  sscanf("123456 ", "%s", buf);
  printf("%s\n", buf);
  结果为:123456
  2. 取指定长度的字符串。如在下例中,取最⼤长度为4字节的字符串。
  sscanf("123456 ", "%4s", buf);
  printf("%s\n", buf);
  结果为:1234
  3. 取到指定字符为⽌的字符串。如在下例中,取遇到空格为⽌字符串。
  sscanf("123456 abcdedf", "%[^ ]", buf);
  printf("%s\n", buf);
  结果为:123456
  4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和⼩写字母的字符串。
  sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
  printf("%s\n", buf);
  结果为:123456abcdedf
  5. 取到指定字符集为⽌的字符串。如在下例中,取遇到⼤写字母为⽌的字符串。
  sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
  printf("%s\n", buf);
  结果为:123456abcdedf
  6、给定⼀个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将⾮'@'的⼀串内容送到buf中
  sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
  printf("%s\n", buf);
  结果为:12DDWDFF
  7、给定⼀个字符串““hello, world”,仅保留world。(注意:“,”之后有⼀空格)
  sscanf(“hello, world”, "%*s%s", buf);
  printf("%s\n", buf);
  结果为:world
  %*s表⽰第⼀个匹配到的%s被过滤掉,即hello被过滤了
  如果没有空格则结果为NULL。
  sscanf的功能很类似于正则表达式, 但却没有正则表达式强⼤,所以如果对于⽐较复杂的字符串处理,建议使⽤正则表达式.
sscanf函数用法详解 x  //-------------------------------------------------------
  sscanf,表⽰从字符串中格式化输⼊
  上⾯表⽰从str中,输⼊数字给x,就是32700
  久以前,我以为c没有⾃⼰的split string函数,后来我发现了sscanf;⼀直以来,我以为sscanf只能以空格来界定字符串,现在我发现我错了。
  sscanf是⼀个运⾏时函数,原形很简单:
  int sscanf(
  const char *buffer,
  const char *format [,
  argument ] ...
  );
  它强⼤的功能体现在对format的⽀持上。
  我以前⽤它来分隔类似这样的字符串2006:03:18:
  int a, b, c;
  sscanf("2006:03:18", "%d:%d:%d", a, b, c);
  以及2006:03:18 - 2006:04:18:
  char sztime1[16] = "", sztime2[16] = "";
  sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2); (此种⽤法结合⽹址:)
  但是后来,我需要处理2006:03:18-2006:04:18
  仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。
  我需要重新设计⼀个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统⼀的风格,
我需要改动很多地⽅,把已有的sscanf替换成我⾃⼰的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满⽽⼊睡;⼀觉醒来,发现其实不必。
  format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使⽤%[]。
  %[]类似于⼀个正则表达式。[a-z]表⽰读取a-z的所有字符,[^a-z]表⽰读取除a-z以外的所有字符。
  所以那个问题也就迎刃⽽解了:
  sscanf("2006:03:18 - 2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2)
下⾯的仅供参考:
本⽂转⾃:
此⽂所有的实验都是基于下⾯的程序:
char str[10];
for (int i = 0; i < 10; i++) str[i] = '!';
执⾏完后str的值为
str = "!!!!!!!!!!"
我们把str的每个字符都初始化为惊叹号,当str的值发⽣变化时,使⽤printf打印str的值,对⽐先前的惊叹号,这样就可以⽅便的观察str发⽣了怎样的变化。下⾯我们做⼏个⼩实验,看看使⽤sscanf和正则表达式格式化输⼊后,str有什么变化。
实验1:
sscanf("123456","%s",str); ---------str的值为 "123456\0!!!"
这个实验很简单,把源字符串"123456"拷贝到str的前6个字符,并且把str的第7个字符设为null字符,也就是\0
实验2:
sscanf("123456","%3s",str); ---------str的值为 "123\0!!!!!!"
看到没有,正则表达式的百分号后⾯多了⼀个3,这告诉sscanf只拷贝3个字符给str,然后把第4个字符设为null字符。
实验3:
sscanf("aaaAAA","%[a-z]",str); ---------str的值为 "aaa\0!!!!!!"
从这个实验开始我们会使⽤正则表达式,括号⾥⾯的a-z就是⼀个正则表达式,它可以表⽰从a到z的任意字符,
在继续讨论之前,我们先来看看百分号表⽰什么意思,%表⽰选择,%后⾯的是条件,⽐如实验1的"%s",s是⼀个条件,表⽰任意字符,"%s"的意思是:只要输⼊的东西是⼀个字符,就把它拷贝给str。实验2的"%3s"⼜多了⼀个条件:只拷贝3个字符。实验3的“%[a-z]”的条件稍微严格⼀些,输⼊的东西不但是字符,还得是⼀个⼩写字母的字符,所以实验3只拷贝了⼩写字母"aaa"给str,别忘了加上null字符。
实验4:
sscanf("AAAaaaBBB","%[^a-z]",str); ---------str的值为 "AAA\0!!!!!!"
对于所有字符,只要不是⼩写字母,都满⾜"^a-z"正则表达式,符号^表⽰逻辑⾮。前3个字符都不是⼩写字符,所以将其拷贝给str,但最后3个字符也不是⼩写字母,为什么不拷贝给str呢?这是因为当碰到不满⾜条件的字符后,sscanf就会停⽌执⾏,不再扫描之后的字符。
实验5:
sscanf("AAAaaaBBB","%[A-Z]%[a-z]",str); ---------段错误
这个实验的本意是:先把⼤写字母拷贝给str,然后把⼩写字母拷贝给str,但很不幸,程序运⾏的时候会发⽣段错误,因为当sscanf扫描到字符a时,违反了条件"%[A-Z]",sscanf就停⽌执⾏,不再扫描之后的字符,所以第⼆个条件也就没有任何意义,这个实验说明:不能使⽤%号两次或两次以上
实验6:
sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); ---------str的值为 "aaa\0!!!!!!"
这个实验出现了⼀个新的符号:%*,与%相反,%*表⽰过滤满⾜条件的字符,在这个实验中,%*[A-Z]过滤了所有⼤写字母,然后再使⽤% [a-z]把之后的⼩写字母拷贝给str。如果只有%*,没有%的话,sscanf不会拷贝任何字符到str,这时sscanf的作⽤仅仅是过滤字符串。
实验7:
sscanf("AAAaaaBBB","%[a-z]",str); ---------str的值为 "!!!!!!!!!!"
做完前⾯⼏个实验后,我们都知道sscanf拷贝完成后,还会在str的后⾯加上⼀个null字符,但如果没有⼀个字符满⾜条件,sscanf不会在str 的后⾯加null字符,str的值依然是10个惊叹号。这个实验也说明了,如果不使⽤%*过滤掉前⾯不需要的字符,你永远别想取得中间的字符。
实验8:
sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); ---------str的值为 "BC\0!!!!!!!"
这是⼀个综合实验,但这个实验的⽬的不是帮我们复习前⾯所学的知识,⽽是展⽰两个值得注意的地⽅:
注意1:%只能使⽤⼀次,但%*可以使⽤多次,⽐如在这个实验⾥⾯,先⽤%*[A-Z]过滤⼤写字母,然后⽤%*[a-z]过滤⼩写字母。
注意2:^后⾯可以带多个条件,且这些条件都受^的作⽤,⽐如^a-z=表⽰^a-z且^=(既不是⼩写字母,也不是等于号)。
实验9:
int k;
sscanf("AAA123BBB456", "%*[^0-9]%i", &k); ---------k的值为123
⾸先,%*[^0-9]过滤前⾯⾮数字的字符,然后⽤%i把数字字符转换成int型的整数,拷贝到变量k,注意参数必须使⽤k的地址。