sscanf和scanf符号输入用法详解

sscanf() - 从一个字符串中读进与指定格式相符的数据. 

函数原型: 
Int sscanf( string str, string fmt, mixed var1, mixed var2 ... ); 
int scanf( const char *format [,argument]... );

说明: sscanf与scanf类似,都是用于输入的

sscanf以固定字符串为输入源     scanf以固定字符串为输入源。 


**其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}

支持集合操作: 
     %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配) 
     %[aB'] 匹配a、B、'中一员,贪婪性 
     %[^a] 匹配非a的任意字符,贪婪性


例子: 
1. 常见用法。 

    char buf[512] = {0}; 
    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、给定一个字符串Dejan/12DDWDF@12,获取 / 和 @ 之间的字符串,先将 "Dejan/"过滤掉,再将非"@的一串内容送到buf中 。

    sscanf("Dejan/12DDWDF@12", "%*[^/]/%[^@]", 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。


8、 scanf的format中出现的非转换字符(%之前或转换字符之后的字符),即此例中的1234用来跳过输入中的相应字符;‘[ ]’的含义与正则表达式中相同,表示匹配其中出现的字符序列;^表示相反。使用[ ]时接收输入的变量必须是有足够存储空间的char、signed char、unsigned char数组。记住  也是转换字符,所以没有s了。    (跳开1 遇到2停下 跳开234 遇到5停下)                                           

        char *s="1try234delete5";sscanf(s, "1%[^2]234%[^5]", s1, s2); 

    char s1[16]={0};
    char s2[16]={0};
    char *s="1try234delete5";
    sscanf(s, "1%[^2]234%[^5]", s1, s2);
    printf("%s\n", s1);
    printf("%s\n", s2);

9、一个提取用户个人资料中邮件地址的例子 

        关键是"%*[^:]:%[^;]"和"%*[^:]:%s"这两个参数的问题 %*[^:]    表示满足"[]"里的条件将被过滤掉,不会向目标参数中写入值。这里的意思是在 第一个':'之前的字符会在写入时过滤掉,'^'是表示否定的意思,整个参数翻译 成白话就是:将在遇到第一个':'之前的(不为':'的)字符全部过滤掉。 : 自然就是跳过':'的意思。 %[^;] 拷贝字符直到遇到';'

#include<cstdlib> 
#include<cstdio> 
using namespace std; 
int main() 
{ 
    char a[20]={0}; 
    char b[20]={0}; 
    //假设email地址信息以';'结束 
    sscanf("email:jimmywhr@gmail.com;","%*[^:]:%[^;]",a); 
    //假设email地址信息没有特定的结束标志 
    sscanf("email:jimmywhr@gmail.com","%*[^:]:%s",b); 
    printf("%s\n",a); 
    printf("%s\n",b); 
    system("pause"); 
    return 0; 
} 

补充:



%[ ] 

        %[ ]表示要读入一个字符集合, 如果[ 后面第一个字符是”^”,则表示反意思。

         [ ]内的字符串可以是1或更多字符组成。空字符集(%[])是违反规定的,可导致不可预知的结果。%[^]也是违反规定的。 
         

%[a-z]

        读取在 a-z 之间的字符串,如果不在此之前则停止,如char s[]="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


%*[^=]   

        前面带 * 号表示不保存变量。跳过符合条件的字符串。

char s[ ]="notepad=1.0.0.1001" ;

char szfilename [32] = "" ;

int i = sscanf( s, "%*[^=]", szfilename ) ; // szfilename=NULL,因为没保存

int i = sscanf( s, "%*[^=]=%s", szfilename ) ; // 遇到=停下,跳过=,输出到最后 
                                               // szfilename=1.0.0.1001

%40c     

        读取40个字符,运行时库不会自动附加空终止符到字符串,也不会读取 40 个字符自动终止 scanf() 函数。 因为库使用缓冲输入,您必须按 ENTER 键终止字符串扫描。 如果您之前按 ENTER,scanf() 读取40个字符,正常显示,并且库继续提示额外的输入直到它读到 40 个字符

%[^=]    

        读取字符串直到碰到’=’号,’^’后面可以带更多字符,如:

char s[]="notepad=1.0.0.1001" ;

char szfilename [32] = "" ;

int i = sscanf( s, "%[^=]", szfilename ) ; // szfilename=notepad     

//如果参数格式是:%[^=:] ,那么也可以从 notepad:1.0.0.1001读取notepad
char s[]="notepad=1.0.0.1001" ;

char szname [32] = "" ;

char szver [32] = ""  ;

sscanf( s, "%[^=]=%s", szname , szver ) ; // szname=notepad, szver=1.0.0.1001

注意:%[]有很大的功能,但是并不是很常用到,主要因为:

1、许多系统的 scanf 函数都有漏洞. (典型的就是 TC 在输入浮点型时有时会出错).

2、用法复杂, 容易出错.

3、编译器作语法分析时会很困难, 从而影响目标代码的质量和执行效率.

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑化草莓熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值