先说一下sscanf函数
int sscanf( const char *buffer, const char *format, [ argument ] ... );
头文件 #include <stdio.h>
参数 | 含义 |
---|---|
buffer | 存储的数据 |
format | 窗体控件字符串 |
argument | 可选自变量 |
locale | 要使用的区域设置 [1] |
返回值
成功:返回成功赋值的字段个数;返回值不包括已读取但未赋值的字段个数。 返回值为 0 表示没有将任何字段赋值。
失败:EOF,表示在第一次读取之前到达字符串结尾
进入正题
在用sscanf 将mac “7c:22:23:44:55:32” 分别存储到mac[0] ~ mac[5]的时候
用%02x获取会段错误
#include <stdio.h>
int main(int argc, char const *argv[])
{
#if 1
int ret = 0;
unsigned char arr[6] = {0x00};
int temp;
ret = sscanf("+mac:7c:22:23:44:55:32\r\nOK\r\n",
"+mac:%02x:%02x:%02x:%02x:%02x:%02x\r\nOK\r\n",
&arr[0],&arr[1],&arr[2],
&arr[3],&arr[4],&arr[5]);
for(int i=0; i<6; i++)
printf("mac[%d]:%2x\r\n", i, arr[i]);
printf("ret = %d\n",ret);
#endif
#if 0
unsigned char ch;
sscanf("6f","%02x",&ch);
printf("%02x %c %d\n",ch,ch,ch);
#endif
return 0;
}
如果用%02hx获取则不会
#include <stdio.h>
int main(int argc, char const *argv[])
{
int ret = 0;
int temp;
unsigned char mac[6] = {0x00};
ret = sscanf("+mac:7c:22:23:44:55:32\r\nOK\r\n",
"+mac:%02hx:%02hx:%02hx:%02hx:%02hx:%02hx\r\nOK\r\n",
&mac[0],&mac[1],&mac[2],
&mac[3],&mac[4],&mac[5]);
for(int i=0; i<6; i++)
printf("mac[%d]:%2x\r\n", i, arr[i]); //mac[0]:7c mac[1]:22 mac[2]:23 mac[3]:44 mac[4]:55 mac[5]:32
printf("ret = %d\n",ret); //ret = 6;
return 0;
}
看网上文章是说,用%02x时,默认是4个字节,但是mac[ n ]是一个字节(char),存储的时候会丢弃掉高3个字节,将低一个字节保存在char中
但是不太理解的是,%02hx为short int,是2个字节,存储的时候应该也会丢弃,但结果却不会段错误
问题解决
因为内存管理机制的问题,我的运行的环境是glibc,将%02x给到mac[5]的时候,mac[6],mac[7],mac[8]都会被赋值为0,但是我们并没有申请mac[6]~mac[8],所以,越界了
而%02xhx可以是因为,arr[6]是一个分隔符,本来就会被自动赋0,但是这样是不严谨的。
最好用%02hhx
#include <stdio.h>
int main(int argc, char const *argv[])
{
int ret = 0;
int temp;
unsigned char mac[6] = {0x00};
ret = sscanf("+mac:7c:22:23:44:55:32\r\nOK\r\n",
"+mac:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\r\nOK\r\n",
&mac[0],&mac[1],&mac[2],
&mac[3],&mac[4],&mac[5]);
for(int i=0; i<6; i++)
printf("mac[%d]:%2x\r\n", i, arr[i]); //mac[0]:7c mac[1]:22 mac[2]:23 mac[3]:44 mac[4]:55 mac[5]:32
printf("ret = %d\n",ret); //ret = 6;
return 0;
}
可以看看这本书:glibc内存管理ptmalloc源代码分析
在线看 glibc内存管理ptmalloc源代码分析
参考文章:https://blog.csdn.net/jeffrey84/article/details/5695807