zoukankan      html  css  js  c++  java
  • sscanf用法(转)

    此文所有的实验都是基于下面的程序:

    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的地址。

    1. #if 0   
    2. 1,sscanf():从一个字符串中读进与指定格式相符的数据.  
    3. 2,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。  
    4. 3,关于正则表达式:  
    5.     (1)%[..],当字符属于方括号里表达式表示的字符集时继续读取,否则停止.方括号里的和正则表达式差不多,^是"排除..."的意思  
    6.     (2)%*[..],直接跳过方括号里的字符集并继续读取  
    7. #endif   
    8.   
    9. #include <iostream>   
    10. using namespace std;  
    11.   
    12. int main()  
    13. {  
    14.     char str[10];  
    15.     for (int i = 0; i < 10; i++) str[i] = '!';  
    16.     cout<<str<<endl;  
    17.     sscanf("123456","%s",str);//---------str的值为 "123456\0!!!"   
    18.     //这个实验很简单,把源字符串"123456"拷贝到str的前6个字符,并且把str的第7个字符设为null字符,也就是\0   
    19.     cout<<str<<endl;  
    20.   
    21.     for (int i = 0; i < 10; i++) str[i] = '!';  
    22.     sscanf("123456","%3s",str); //---------str的值为 "123\0!!!!!!"   
    23.     //看到没有,正则表达式的百分号后面多了一个3,这告诉sscanf只拷贝3个字符给str,然后把第4个字符设为null字符。   
    24.     cout<<str<<endl;  
    25.   
    26.     for (int i = 0; i < 10; i++) str[i] = '!';  
    27.     sscanf("aaaAAA","%[a-z]",str);// ---------str的值为 "aaa\0!!!!!!"   
    28.     //从这个实验开始我们会使用正则表达式,括号里面的a-z就是一个正则表达式,它可以表示从a到z的任意字符,   
    29.     //在继续讨论之前,我们先来看看百分号表示什么意思,%表示选择,%后面的是条件,比如实验1的"%s",s是一个条件,表示任意字符,"%s"的意思是:只要输入的东西是一个字符,就把它拷贝给str。实验2的"%3s"又多了一个条件:只拷贝3个字符。实验3的“%[a-z]”的条件稍微严格一些,输入的东西不但是字符,还得是一个小写字母的字符,所以实验3只拷贝了小写字母"aaa"给str,别忘了加上null字符。   
    30.     cout<<str<<endl;  
    31.   
    32.     for (int i = 0; i < 10; i++) str[i] = '!';  
    33.     sscanf("AAAaaaBBB","%[^a-z]",str);// ---------str的值为 "AAA\0!!!!!!"   
    34.     //对于所有字符,只要不是小写字母,都满足"^a-z"正则表达式,符号^表示逻辑非。前3个字符都不是小写字符,所以将其拷贝给str,但最后3个字符也不是小写字母,为什么不拷贝给str呢?这是因为当碰到不满足条件的字符后,sscanf就会停止执行,不再扫描之后的字符。   
    35.     cout<<str<<endl;  
    36.   
    37.     /* 
    38.     for (int i = 0; i < 10; i++) str[i] = '!'; 
    39.     sscanf("AAAaaaBBB","%[A-Z]%[a-z]",str);// ---------段错误 
    40.     //这个实验的本意是:先把大写字母拷贝给str,然后把小写字母拷贝给str,但很不幸,程序运行的时候会发生段错误,因为当sscanf扫描到字符a时,违反了条件"%[A-Z]",sscanf就停止执行,不再扫描之后的字符,所以第二个条件也就没有任何意义,这个实验说明:不能使用%号两次或两次以上 
    41.     cout<<str<<endl; 
    42.     */  
    43.   
    44.     for (int i = 0; i < 10; i++) str[i] = '!';  
    45.     sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); //---------str的值为 "aaa\0!!!!!!"   
    46.     //这个实验出现了一个新的符号:%*,与%相反,%*表示过滤满足条件的字符,在这个实验中,%*[A-Z]过滤了所有大写字母,然后再使用%[a-z]把之后的小写字母拷贝给str。如果只有%*,没有%的话,sscanf不会拷贝任何字符到str,这时sscanf的作用仅仅是过滤字符串。   
    47.     cout<<str<<endl;  
    48.   
    49.     for (int i = 0; i < 10; i++) str[i] = '!';  
    50.     sscanf("AAAaaaBBB","%[a-z]",str);// ---------str的值为 "!!!!!!!!!!"   
    51.     //做完前面几个实验后,我们都知道sscanf拷贝完成后,还会在str的后面加上一个null字符,但如果没有一个字符满足条件,sscanf不会在str 的后面加null字符,str的值依然是10个惊叹号。这个实验也说明了,如果不使用%*过滤掉前面不需要的字符,你永远别想取得中间的字符。   
    52.     cout<<str<<endl;  
    53.   
    54.     for (int i = 0; i < 10; i++) str[i] = '!';  
    55.     sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); //---------str的值为 "BC\0!!!!!!!"   
    56.     //这是一个综合实验,但这个实验的目的不是帮我们复习前面所学的知识,而是展示两个值得注意的地方:   
    57.     //注意1:%只能使用一次,但%*可以使用多次,比如在这个实验里面,先用%*[A-Z]过滤大写字母,然后用%*[a-z]过滤小写字母。   
    58.     // 注意2:^后面可以带多个条件,且这些条件都受^的作用,比如^a-z=表示^a-z且^=(既不是小写字母,也不是等于号)。   
    59.     cout<<str<<endl;  
    60.   
    61.     for (int i = 0; i < 10; i++) str[i] = '!';  
    62.     int k;  
    63.     sscanf("AAA123BBB456""%*[A-Z]%i", &k); //---------k的值为123   
    64.     //首先,%*[^0-9]过滤前面非数字的字符,然后用%i把数字字符转换成int型的整数,拷贝到变量k,注意参数必须使用k的地址。    cout<<str<<endl;   
    65.     cout<<k<<endl;  
    66.     return 0;  
    67. }  
  • 相关阅读:
    随便 构思 一个 计算 解析积分 的 简单 的 数学软件
    为什么要 拿 光 的 干涉条纹 宽度 变化 作为 判断 光速 变化 的 依据 ?
    相对论 的 几个问题
    设计 逻辑电路 的 开关元件 (2)
    设计 逻辑电路 的 开关元件
    用 逻辑电路 实现一个 开平方 算法
    小梦 在 民科吧 发了一个 用 四则运算 开平方 的 帖
    物理学 的 基本原理
    和 小梦 探讨 一个 经典力学 问题
    二分法 比 跨越步进法 快
  • 原文地址:https://www.cnblogs.com/newlist/p/2578161.html
Copyright © 2011-2022 走看看