用sscanf 将mac转化为字符串 段错误问题

先说一下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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值