前言
摘要:当你获得一串数据报文时,你是怎么截取它你想要的数据呢。比如你从某个地方获得了一个一串数据报,这串数据报是:helloworld,为char *类型,传统的获取方法有:
- 通过数组下标的方式
- 指针的方式
- 定义一个数组通过strcpy,或者strcat等方式进行获取。
这些方法其实都可以,但是假设我有成百上千个数据,想通过判断某个字符来截取,你是否要写一个if-else函数?又或者我想把获得的数据转换为其他类型进行运算,我又是否要用其他函数来进行转换?有没有一步到位的函数?有的,他就是我们今天的主人公----------sscanf(),头文件是#include <string.h>。
一、sscanf是什么?
sscanf 读取格式化的字符串中的数据。其实说白了就是scanf的升级版。但是scanf一般都读键盘上输入的数据,不能读取其他地方来的数据。
二、sscanf的功能
- 可以把字符串转化为任意类型的数据
- 获取字符中间的字符串
- 可以把一个字符串拆分成多个字符串
- 分割以某字符隔开的字符串
- 取指定长度的字符串
…
不说这么多了,主要看代码演示把
1.代码演示
代码如下(示例):
1.功能:分割成多个字符串
#include <string>
#include <stdio.h>
int main()
{
//sscanf读取的格式
//%d 读0-9的字符转成整数
//%nd 读n个0-9的字符转成整数
int year = 0;
int month = 0;
int day = 0;
char str[] = "20210728";
sscanf(str,"%4d%2d%2d",&year,&month,&day);
printf("%d : %d : %d\n", year, month,day);
return 0;
}
运行结果:
2.功能:跳过0-9的字符
#include <string>
#include <stdio.h>
int main()
{
//%*d 代表跳过所有0-9的字符
//%*nd 代表跳过n个所有0-9的字符
int year = 0;
char str[] = "20210728";
sscanf(str,"%*3d%3d",&year);
printf("%d\n",year);
return 0;
}
解析:首先通过%*3d来跳过三个0-9的字符202,之后通过%3d来获取之后的三个字符107并转换为int类型.
3.功能:跳过指定的字符
#include <string>
#include <stdio.h>
int main()
{
//只要遇到\n 空格 \0 都会停止匹配
//%s 只要是字符就要
//%ns 读取n个字符
//%*s 跳过所有的字符
//%*ns 跳过n个字符
int year = 0;
char buf[128] = "";
char str[] = "acdef20hehe210728";
//sscanf(str,"%*7s%4s",buf);
sscanf(str, "%*11s%3d", &year);
printf("%d\n", year);
//printf("%s\n",buf);
return 0;
}
分析:该函数只要遇到\n 空格 \0 都会停止匹配,首先通过%*11s跳过11个字符,后通过%3d获取后面三个字符并转换为转型,如果转换,就直接使用%3s就可以了。
运行结果:
4.功能:取指定的多个字符
#include <string>
#include <stdio.h>
int main()
{
int year = 0;
int day = 0;
char buf[128] = "";
char str[] = "acdgfanlg2034effafgg21";
// %[abcdef] 取abcdef的字符
sscanf(str,"%[a-z]",buf);//取a-z
// sscanf(str, "%*[a-z]%*[0-9]%[a-z]", buf);
printf("%s\n",buf);
return 0;
}
分析:通过%[]来取值,比如%[a-z]就是取得a-z之间的字符,并存进buf里面
运行结果:
5.功能:跳过指定的多个字符
#include <string>
#include <stdio.h>
int main()
{
int year = 0;
int day = 0;
char buf[128] = "";
char str[] = "acdgfanlg2034effafgg21";
//%[abcdef] 取abcdef的字符
//%*[abcdef] 跳过abcdef的字符
//%[a-z] 取a-z
//%*[a-z] 跳过a-z的字符
//%[0-9] 取0-9字符
//%*[0-9] 跳过0-9字符
sscanf(str, "%*[a-z]%*[0-9]%[a-z]", buf);
printf("%s\n",buf);
return 0;
}
分析:先跳过a-z的值如果不是的话就停止匹配,然后在跳过0-9的字符,最后再取得a-z的字符。
运行结果:
6.功能:取得不是x的字符,碰到x将会停止
int main()
{
//%[^x] 取不是字符x的字符
int year = 0;
int day = 0;
char buf[128] = "";
char str[] = "aAcZdg23f!a45nlg#effafgg21";
//要#号前面的字符
sscanf(str,"%[^#!]",buf);
printf("%s\n",buf);
return 0;
}
分析 :取不是#!的字符,如果碰到了#或者!将会停止匹配
7.功能:跳过不是x的字符,碰到x指针将会指向x
int main()
{
//%*[^x] 跳过不是字符x的字符
int year = 0;
int day = 0;
char buf[128] = "";
char str[] = "aAcZdg23f!a45nlg#effafgg21";
//要#号后面的字符
sscanf(str,"%*[^#]#%s",buf);
printf("%s\n",buf);
return 0;
}
分析:跳过不是#号的字符,如果碰到#号,指针将会指到#号,跳过#号之后取后面的值。
运行结果:
总结
总结:掌握了这个字符串,基本上对数据帧的解析已经拿捏了。不过要注意的是取值的时候碰到只要遇到\n 空格 \0 都会停止匹配,用%*跳过就没问题,