当前位置:首页 » 《休闲阅读》 » 正文

C语言全网最全sscanf函数用法,没有的评论区提,随时更新

3 人参与  2024年09月09日 17:21  分类 : 《休闲阅读》  评论

点击全文阅读


        本教程分初级、进阶、实战用例,有基础的直接跳到后面吧。本文主要拿AT指令做例子。写得不好别喷,合理的要求可以提出来我尽力改。 本教程应该足以面对大部分的解析。

        最后部分主要是实战为主。各位有想解析的字符串可以放到评论区,比较经典的我会放到文章里。

一、函数原型解析

        直接看以下:

#include <stdio.h>  /* 引用这个标准的头文件 *//** * @function: sscanf * @brief C语言格式化输入函数,可用作解析字符串中的参数。 * @param {char} *str: 源字符串,也就是要被解析的字符串。 * @param {char} *format: 解析格式。 * @param {...} 要取出的值,要取几个?要取什么类型的?排好队,一个一个来 * @return {int} 返回int类型,返回值代表解析了几个值。 */int sscanf(const char *str, const char *format, ...);

二、初级用法

        这里包含了最基础的%s, %d, %f的用法。你想取出什么类型的值就用什么类型的方法。新手一定一定要注意格式!

1. 取字符串 %s

        这里会把你输入的   AT+COM=  过滤掉,取出后面的所有字符串。

/* * @Author: Troubadour 2276791354@qq.com * @Date: 2024-04-20 19:47:51 * @LastEditors: Troubadour 2276791354@qq.com * @LastEditTime: 2024-04-20 20:10:09 * @Version: * @Description: */#include <stdio.h>#define STR     "AT+COM=aabbcc"void main(void){    int result = 0;    char str_para1[50] = {0};    result = sscanf(STR, "AT+COM=%s", str_para1);    printf("result------> %d \r\n", result);    printf("parameter1--> %s \r\n", str_para1);}

        输出:

result------> 1 parameter1--> aabbcc

        如果你想只取指定数量的字符串,比如3个两个字符串:

sscanf("AT+COM=aabbcc", "AT+COM=%3s", str_para1);

        输出:

result------> 1 parameter1--> aab
2. 取整形 %d  或者  %ld。

        这里会把你输入的   AT+COM=  过滤掉,取出后面的整形。

        注意!整形和浮点型这种不是类型的要加取地址符 ‘&’,因为要给你的参数赋值。另外,如果你想取出来的值放在非int类型的变量上,比如单片机常用的uint8_t    uint16_t  uint32_t 这种,不要直接读,程序容易跑飞!

/* * @Author: Troubadour 2276791354@qq.com * @Date: 2024-04-20 19:47:51 * @LastEditors: Troubadour 2276791354@qq.com * @LastEditTime: 2024-04-20 20:10:09 * @Version: * @Description: */#include <stdio.h>#define STR     "AT+COM=123456,111222333"void main(void){    int result = 0;    int para1 = 0;    long long para2 = 0;    result = sscanf(STR, "AT+COM=%d,%ld", &para1, &para2);    printf("result------> %d \r\n", result);    printf("parameter1--> %d \r\n", para1);    printf("parameter2--> %ld \r\n", para2);}

输出:

result------> 2 parameter1--> 123456 parameter2--> 111222333

        其它整形类型变量读取方法:

/* * @Author: Troubadour 2276791354@qq.com * @Date: 2024-04-20 19:47:51 * @LastEditors: Troubadour 2276791354@qq.com * @LastEditTime: 2024-04-20 20:35:41 * @Version: * @Description: */#include <stdio.h>#define STR     "AT+COM=11,22"typedef unsigned charuint8_t;typedef unsigned shortuint16_t;void main(void){    int result = 0;    int para1 = 0;    int para2 = 0;    uint8_t value1 = 0;    uint16_t value2 = 0;    result = sscanf(STR, "AT+COM=%d,%ld", &para1, &para2);    value1 = (uint8_t)para1;    value2 = (uint16_t)para2;    printf("result------> %d \r\n", result);    printf("parameter1--> %d \r\n", para1);    printf("parameter2--> %ld \r\n", para2);    printf("value1------> %d \r\n", value1);    printf("value2------> %ld \r\n", value2);}

输出:

result------> 2 parameter1--> 11parameter2--> 22value1------> 11value2------> 22

3. 取浮点型形 %f,建议用%lf。

        这里会把你输入的   AT+COM=  过滤掉,取出后面的浮点型。

        不建议使用float,原因精度差,不信且看例子。非要用或者某些原因限制,那你把值读出来再强制类型转成float,比如将下面para2强制类型转换成float:para1 = (float)para2;

/* * @Author: Troubadour 2276791354@qq.com * @Date: 2024-04-20 19:47:51 * @LastEditors: Troubadour 2276791354@qq.com * @LastEditTime: 2024-04-20 20:20:31 * @Version: * @Description: */#include <stdio.h>#define STR     "AT+COM=1234.123456,222333.444555666"void main(void){    int result = 0;    float para1 = 0;    /* 精度差,建议用 double */    double para2 = 0;    result = sscanf(STR, "AT+COM=%f,%lf", &para1, &para2);    printf("result------> %d \r\n", result);    printf("parameter1--> %f \r\n", para1);    printf("parameter2--> %.10f \r\n", para2);}

输出:

result------> 2 parameter1--> 1234.123413       parameter2--> 222333.4445556660
4. 其它格式:
%c 一个单一的字符  %d 一个十进制整数  %i 一个整数  %e, %f, %g 一个浮点数  %o 一个八进制数  %s 一个字符串  %x 一个十六进制数  %p 一个指针  %n 一个等于读取字符数量的整数  %u 一个无符号整数  %[ ] 一个字符集 (正则就使用这个,而且仅支持贪婪模式,能匹配个多少就匹配多少个) %% 一个精度符

三、进阶用法字符集: %[]

1. 字符串取值限定用法

        懂点基础了可以看点稍微复杂点的了。现在开始使用一些特殊符号。先来个  %[^,] 用法。

%:读取一个或多个。[]:表示开始一个扫描集(scan set)。扫描集用于匹配一系列字符中的任何一个字符。^:表示在扫描集中,^字符用作否定前缀。例如: [^A] 表示匹配直到遇见字符A停止(匹配出来的字符串不包字符A)。又例如: [^,] 表示匹配直到遇见逗号,停止(匹配出来的字符串不包逗号,)。

        例如,现在有这么一串字符串,取出后面的所有值。

AT+COM=aabbcc,1234,12.34
/* 输入 */sscanf("AT+COM=aabbcc,1234,12.34", "AT+COM=%[^,],%d,%lf", para1, &para2, &para3);/* 输出 */aabbcc123412.340000

如果是空格作为间隔,则使用:

/* 输入 */sscanf("AT+COM=aabbcc 1234 12.34", "AT+COM=%[^ ] %d %lf", para1, &para2, &para3);/* 输出 */aabbcc123412.340000

为什么不能用%s,以下错误示范!!!

/* 输入 */sscanf("AT+COM=aabbcc,1234,12.34", "AT+COM=%s,%d,%lf", para1, &para2, &para3);/* 输出 */aabbcc,1234,12.3400.000000

2. 使用 * 号忽略某个值或者忽略某种类型

        取值时把%[^,]改成%*[^,]可以忽略这个字符串,这时输出只有整形和浮点型

/* 输入 */sscanf("AT+COM=aabbcc,1234,12.34", "AT+COM=%*[^,],%d,%lf", &para2, &para3);/* 输出 */123412.340000

         把%d改成%*d可以再忽略一个整形,这时输出只有浮点型

/* 输入 */sscanf("AT+COM=aabbcc,1234,12.34", "AT+COM=%*[^,],%*d,%lf", &para3);/* 输出 */12.340000

3. 取出限定的字符

        在中括号 [] 放入想要匹配的几个字符,符合条件就会读取。

/* 输入 */sscanf("AT+COM=abc,1234,12.34", "AT+COM=%[abcdef],%d,%lf", para1, &para2, &para3);/* 输出 */abc 1234 12.340000

         匹配所有的小写字母%[a-z]

/* 输入 */sscanf("AT+COM=abcuehwiuh,1234,12.34", "AT+COM=%[a-z],%d,%lf", para1, &para2, &para3);/* 输出 */abcuehwiuh123412.340000

          加上A-Z可以匹配所有的大小写字母。

/* 输入 */sscanf("AT+COM=AAabcuehwiuh,1234,12.34", "AT+COM=%[a-zA-Z],%d,%lf", para1, &para2, &para3);/* 输出 */AAabcuehwiuh 1234 12.340000

        匹配所有的数字%[0-9]。注意,这里匹配出来的是还是字符串,不是整形!

/* 输入 */sscanf("AT+COM=01238889,1234,12.34", "AT+COM=%[0-9],%d,%lf", para1, &para2, &para3);/* 输出 */01238889 1234 12.340000

        三种其实可以整合到一起,取出不含特殊符号的字符串

/* 输入 */sscanf("AT+COM=AAabcuehwiuh123,1234,12.34", "AT+COM=%[a-zA-Z0-9],%d,%lf", para1, &para2, &para3);/* 输出 */AAabcuehwiuh123 123412.340000

         匹配一些含特殊符号的字符串,这里注意,如果你想匹配符号 - 需要放到最后面,不然就出错匹配不了,这是一个非常特殊的符号。

/* 输入 */sscanf("AT+COM=***+-{}##$$,1234,12.34", "AT+COM=%[*+{}$# -],%d,%lf", para1, &para2, &para3);/* 输出 */***+-{}##$$ 1234 12.340000

四、高阶用法:

        这里主要是实战为主。

1. 解析时间日期

/* 输入 */result = sscanf("2024-04-20 Sat 22:00:01", "%d-%d-%d %3[^ ] %d:%d:%d",        &year, &mon, &day, week, &hour, &min, &sec);/* 输出 */result------> 7 2024 420Sat2201

2.前面带乱码的情况下过滤并读取

        主要使用%*[^A]的方法一个一个过滤,如果一般过滤到第3个也就差不多了。

/* 输入 */result = sscanf("xxxLuanMaxxxA  AT+COM=Time,12:20:53\r\n",                "%*[^A]%*[^T]%*[^+]+COM=%10[^,],%d:%d:%d",                type, &hour, &min, &sec);/* 输出 */result------> 4 Time 122053

如果你有复杂解析不了的字符串,欢迎评论区发出来,我会挑一些经典的放进文章。

持续更新.............


点击全文阅读


本文链接:http://zhangshiyu.com/post/157475.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1