`
kmplayer
  • 浏览: 509759 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

仍段代码下来:
#if 0
1,sscanf():从一个字符串中读进与指定格式相符的数据.
2,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
3,关于正则表达式:
    (1)%[..],当字符属于方括号里表达式表示的字符集时继续读取,否则停止.方括号里的和正则表达式差不多,^是"排除..."的意思
    (2)%*[..],直接跳过方括号里的字符集并继续读取
#endif

#include <iostream>
using namespace std;

int main()
{
    char str[10];
    for (int i = 0; i < 10; i++) str[i] = '!';
    cout<<str<<endl;
    sscanf("123456","%s",str);//---------str的值为 "123456\0!!!"
    //这个实验很简单,把源字符串"123456"拷贝到str的前6个字符,并且把str的第7个字符设为null字符,也就是\0
    cout<<str<<endl;

    for (int i = 0; i < 10; i++) str[i] = '!';
    sscanf("123456","%3s",str); //---------str的值为 "123\0!!!!!!"
    //看到没有,正则表达式的百分号后面多了一个3,这告诉sscanf只拷贝3个字符给str,然后把第4个字符设为null字符。
    cout<<str<<endl;

    for (int i = 0; i < 10; i++) str[i] = '!';
    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字符。
    cout<<str<<endl;

    for (int i = 0; i < 10; i++) str[i] = '!';
    sscanf("AAAaaaBBB","%[^a-z]",str);// ---------str的值为 "AAA\0!!!!!!"
    //对于所有字符,只要不是小写字母,都满足"^a-z"正则表达式,符号^表示逻辑非。前3个字符都不是小写字符,所以将其拷贝给str,但最后3个字符也不是小写字母,为什么不拷贝给str呢?这是因为当碰到不满足条件的字符后,sscanf就会停止执行,不再扫描之后的字符。
    cout<<str<<endl;

    /*
    for (int i = 0; i < 10; i++) str[i] = '!';
    sscanf("AAAaaaBBB","%[A-Z]%[a-z]",str);// ---------段错误
    //这个实验的本意是:先把大写字母拷贝给str,然后把小写字母拷贝给str,但很不幸,程序运行的时候会发生段错误,因为当sscanf扫描到字符a时,违反了条件"%[A-Z]",sscanf就停止执行,不再扫描之后的字符,所以第二个条件也就没有任何意义,这个实验说明:不能使用%号两次或两次以上
    cout<<str<<endl;
    */

    for (int i = 0; i < 10; i++) str[i] = '!';
    sscanf("AAAaaaBBB","%*[A-Z]%[a-z]",str); //---------str的值为 "aaa\0!!!!!!"
    //这个实验出现了一个新的符号:%*,与%相反,%*表示过滤满足条件的字符,在这个实验中,%*[A-Z]过滤了所有大写字母,然后再使用%[a-z]把之后的小写字母拷贝给str。如果只有%*,没有%的话,sscanf不会拷贝任何字符到str,这时sscanf的作用仅仅是过滤字符串。
    cout<<str<<endl;

    for (int i = 0; i < 10; i++) str[i] = '!';
    sscanf("AAAaaaBBB","%[a-z]",str);// ---------str的值为 "!!!!!!!!!!"
    //做完前面几个实验后,我们都知道sscanf拷贝完成后,还会在str的后面加上一个null字符,但如果没有一个字符满足条件,sscanf不会在str 的后面加null字符,str的值依然是10个惊叹号。这个实验也说明了,如果不使用%*过滤掉前面不需要的字符,你永远别想取得中间的字符。
    cout<<str<<endl;

    for (int i = 0; i < 10; i++) str[i] = '!';
    sscanf("AAAaaaBC=","%*[A-Z]%*[a-z]%[^a-z=]",str); //---------str的值为 "BC\0!!!!!!!"
    //这是一个综合实验,但这个实验的目的不是帮我们复习前面所学的知识,而是展示两个值得注意的地方:
    //注意1:%只能使用一次,但%*可以使用多次,比如在这个实验里面,先用%*[A-Z]过滤大写字母,然后用%*[a-z]过滤小写字母。
    // 注意2:^后面可以带多个条件,且这些条件都受^的作用,比如^a-z=表示^a-z且^=(既不是小写字母,也不是等于号)。
    cout<<str<<endl;

    for (int i = 0; i < 10; i++) str[i] = '!';
    int k;
    sscanf("AAA123BBB456", "%*[A-Z]%i", &k); //---------k的值为123
    //首先,%*[^0-9]过滤前面非数字的字符,然后用%i把数字字符转换成int型的整数,拷贝到变量k,注意参数必须使用k的地址。    cout<<str<<endl;
    cout<<k<<endl;
    return 0;
}

分享到:
评论

相关推荐

    c语言 sscanf,scanf,fscanf正则表达式用法

    每种语言都对正则表达式有着不同程度的支持,在C语言中,有输入功能的这三个函数对正则表达式的支持并不强大,但是我们还是有必要了解一下。 首先来看看他们的原型: #include int scanf(const char *format, ...)...

    cssanf-支持所有正则表达式的sscanf_s

    3. 调用`cssanf`函数:使用`cssanf`函数,将正则表达式和待解析的字符串作为参数传递。函数会返回匹配成功与否的结果,并可以通过返回值和指针参数获取匹配到的数据。 4. 检查匹配结果:根据`cssanf`的返回值,判断...

    sscanf函数的高级用法

    sscanf函数是C语言标准库中的一个输入函数,它可以从一个字符串中按照指定的格式读取数据,并将数据存储在变量中...正确的应用sscanf函数的高级特性可以有效地提取和解析所需数据,提高程序对复杂数据格式的处理能力。

    sscanf练习详解-分割字符串

    在这种情况下,可能需要使用更复杂的方法,如正则表达式或者自定义的解析逻辑。 总结起来,`sscanf`是C/C++中用于从字符串中提取数据的强大工具,通过灵活的转换说明符可以实现多种数据类型的读取。理解并熟练运用`...

    关于sscanf函数

    ### 关于sscanf函数 #### 一、简介 `sscanf`函数是C语言标准库中的一个重要函数,用于从字符串中解析数据,并将其存储到指定的变量中。它的工作方式与`scanf`函数非常相似,但`scanf`是从标准输入(如键盘)读取...

    C语言函数sscanf 的用法-综合文档

    需要注意的是,sscanf 函数并不是正则表达式,但是它可以实现一些简单的字符串匹配和提取操作。如果需要进行复杂的字符串处理,建议使用正则表达式。 sscanf 函数是一个非常有用的输入函数,它可以帮助我们从字符串...

    matlab_中sscanf__函数的使用.doc

    Matlab 中 sscanf 函数的使用 Matlab 中的 sscanf 函数是用于从一个字符串中读取与指定格式相符的数据。该函数的原型为 `Int sscanf( const char *, const ...但是,如果需要处理复杂的字符串,建议使用正则表达式。

    sscanf 表达式详解

    ### sscanf 表达式详解 #### 一、概述 `sscanf`是C语言标准库中的一个函数,用于从字符串中解析数据,并将其存储到指定的变量中。它的工作方式与`scanf`相似,但其输入来源不是键盘而是内存中的字符串。`sscanf`...

    sscanf()的用法

    然而,对于更复杂的数据解析任务,尤其是涉及到正则表达式的情况,可能需要使用其他工具或库,因为`sscanf()`的功能相对较弱。 在处理日期或时间字符串时,`sscanf()`可以方便地将字符串分解成各个部分。例如: ```...

    sscanf 详解

    然而,尽管它的功能类似于正则表达式,但在处理更为复杂的字符串模式时,可能不如正则表达式那样灵活和强大。因此,在面对复杂的字符串处理需求时,推荐考虑使用正则表达式或其他专门的字符串处理库。

    简单的词法分析器(c语言)

    首先,我们需要定义一个词法规则,这通常通过正则表达式来完成。例如,C语言的关键字如`int`, `for`, `while`等,可以通过预定义的字符串数组来识别。标识符由字母、数字或下划线组成,且不能以数字开头,可以用正则...

    6 MATLAB深入学习字符串.zip

    1. 正则表达式:MATLAB支持正则表达式操作,如`regexp`和`regexprep`函数,用于模式匹配和替换。 2. 字符串函数库:MATLAB R2016b及以后版本引入了字符串数组,这是一类特殊的数组,可以更方便地处理字符串。`...

    matlab开发-文件中的grepValues

    在MATLAB中,可以使用`strfind`或正则表达式`regexp`来实现这一功能。正则表达式提供了更灵活的搜索模式,可以处理复杂的数据模式匹配。 3. **数据提取**:找到匹配的行后,函数会进一步解析这些行以提取需要的值。...

    C语言中的sscanf()函数使用详解

    这个例子中,`sscanf()`函数被用来解析包含多个单词的字符串、读取指定长度的字符串以及通过正则表达式匹配字符串中的数字、小写字母和大写字母。 需要注意的是,由于`sscanf()`从已知字符串中读取,所以不会像`...

    matlab数组字符串MATLAB深入学习字符串 算法开发、数据可视化、数据分析以及数值计算 Matlab课程 教程 进阶 资源

    5. **正则表达式**:MATLAB中的`regexp`和`regexprep`函数允许使用正则表达式进行复杂文本模式匹配和替换,这对于数据清洗和提取特定格式的信息非常有用。 6. **字符串函数库**:MATLAB提供了一系列字符串函数,如`...

    linux环境歌词解析系统

    4. **正则表达式**:为了匹配和提取LRC文件中的时间戳和歌词,正则表达式是非常有用的工具。它可以方便地匹配特定模式的字符串,例如`\[([0-9]{2}):([0-9]{2})\.([0-9]{2})\]`可以用来匹配时间戳。 5. **数据结构**...

    matlab基础编程:6 MATLAB深入学习字符串.zip

    7. **正则表达式**:MATLAB支持正则表达式操作,通过 `regexp` 和 `regexprep` 函数实现复杂模式匹配和替换。例如,`matches = regexp(str, '\d+')` 可以找到字符串中的所有数字。 8. **字符串数组**:在MATLAB R...

    最全PHP常用函数解析

    `quotemeta()`函数转义字符串中的特殊字符,防止它们被当作正则表达式的一部分。`rtrim()`与`chop()`类似,用于去除字符串右侧的特定字符。`setlocale()`用于设置本地化信息,影响到日期、时间和其他文化相关的格式...

    最全MATLAB函数手册.pdf

    - `regexp` 和 `regexpi`:正则表达式匹配。 - `sprintf` 和 `sscanf`:格式化字符串输入和输出。 - `strcat`:字符串连接。 - `strcmp` 和 `strcmpi`:比较字符串。 - `strfind`:在字符串中查找子串的位置。 ...

Global site tag (gtag.js) - Google Analytics