菜鸟笔记
提升您的技术认知

sscanf函数用法

定义函数 int sscanf (const char *str,const char * format,........);       
 函数说明         
                  sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
                 返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。 返回0表示失败    否则,表示正确格式化数据的个数    例如:sscanf(str,"%d%d%s", &i,&i2, &s);    如果三个变成都读入成功会返回3。    如果只读入了第一个整数到i则会返回1。证明无法从str读入第二个整数。
定义太抽象了,我们还是先来看一下常见的用法吧:
(1)sscanf("zhoue3456 ", "%4s", str); //取指定长度的字符串       
          printf("str=%s\n", str);   //str="zhou";
(2)sscanf("zhou456 hedf", "%[^ ]", str); //取到指定字符为止的字符串,取遇到空格为止字符串    
          printf("str=%s\n", str);  //str=zhou456;
(3)sscanf("654321abcdedfABCDEF", "%[1-9a-z]", str); //取仅包含指定字符集的字符串
          printf("str=%s\n", str);  //str=654321abcded,只取数字和小写字符
(4)sscanf("BCDEF123456abcdedf", "%[^a-z]", str); //取到指定字符集为止的字符串       
           printf("str=%s\n", str);  //  str=BCDEF123456, 取遇到大写字母为止的字符串
(5)int a,b,c;
          sscanf("2015.04.05", "%d.%d.%d", &a,&b,&c); //取需要的字符串   
          printf("a=%d,b=%d,c=%d",a,b,c);  //  a=2015,b=4,c=5
通过上面这几个例子相信大家对sscanf的用法会有一个直观的理解了,下面我们再来看一下更复杂一些的例子:
(6)给定一个字符串“abcd&hello$why”,现在我想取出&与$之间的字符串怎么办呢
        sscanf("abcd&hello$why", "%*[^&]&%[^$]", str );<span style="white-space:pre"></span>printf("str=%s\n",str);  //str="hello"
       其中%[]类似于一个正则表达式,如[a-z]表示读取所有a-z的字符,[^a-z]表示读取所有非小写字母的字符。那么在这里%*[^&]表示先过滤掉abcd,然后以&隔开,后面还剩hello$why,然后将$之前非$的字符提取到str中。
(7)给定一个字符串“what, time”,如果我想仅保留time,那该怎么办呢?(,后面有个空格)
         sscanf(“what, time”, "%*s%s", str );<span style="white-space:pre"></span>printf("str=%s\n",str);  //str="time"
         其中%*s表示第一个被匹配到的字符串what,被过滤掉了,如果没有空格,则结果为NULL。其实“what, time”被空格分割成了两个字符串"what,"和"time".
然而有人会问,C语言中的scanf和sscanf有什么区别和联系呢?OK,sscanf和scanf确实很类似,两者都是用于输入。只是后者以屏幕stidin为输入源,而前者是以字符串为输入源,仅此而已。
函数原型: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] = ; 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] = ; 
             sscanf(sourceStr, "%*s%s", buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
          cout << buf<< endl; 结果为:world 
支持集合操作: %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
                            %[aB'] 匹配a、B、'中一员,贪婪性

                               %[^a] 匹配非a的任意字符,贪婪性

PS:

  • sscanf与scanf类似,都是用于输入的,前者以固定字符串为输入源,只是后者以屏幕(stdin)为输入源。  
  • 关于正则表达式:  
  •     (1)%[..],当字符属于方括号里表达式表示的字符集时继续读取,否则停止.方括号里的和正则表达式差不多,^是"排除..."的意思  
  •     (2)%*[..],直接跳过方括号里的字符集并继续读取