【C语言小技巧】16进制字符串与字符串互转_十六进制转字符串

16进制字符串转字符串

言归正传,现在我们先来看看16进制字符串转字符串,大致的逻辑就是将16进制字符串每两个字符组合在一起得到一个16进制的字符串,然后再打包转成对应的字符。我们可以利用库函数strtol(),其函数声明为long int strtol(const char *str, char **endptr, int base),该函数的功能是把参数 str 所指向的字符串根据给定的 base 转换为一个长整数(类型为 long int 型),base 必须介于 236(包含)之间,或者是特殊值 0

  1. 参数:
    • str – 要转换为长整数的字符串
    • endptr – 对类型为char*的对象的引用,其值由函数设置为str中数值后的下一个字符
    • base – 基数,必须介于236(包含)之间,或者特殊值0。如果base0,则会根据字符串的前缀来判断进制
  2. 返回值:
    函数返回被转换的长整型整数值。如果输入字符串不符合数字格式,strtol() 将返回 0。如果转换结果超出了 long 整数的表示范围,那么将产生溢出,并设置 errnoERANGE。你可以使用 <errno.h> 头文件中的 errno 变量来检查是否有溢出发生。

现在我们来进行实战操作,如下示例:

#include <stdlib.h> // 要使用strtol()库函数,需要包含头文件

char data[] = "48656C6C6F20576F726C6421210D0A"; // 假如,我们接收到这样的数据
char res[32]; // 储存转换后的结果

int hex\_str\_2\_str(char \*dest, char \*src)
{
    int len = strlen(src); // 获取接收数据长度
    int i,j;

    for (i = 0, j = 0; i < len; i+=2) { // 每次取两个字符
        char tmp_buf[3]; // 每两个字符组成一个16进制字符串,同时结尾需要空字符来告诉编译器我们的是字符串
        char \*endptr; // 保存已转换数值后的下一个字符

        // 以下为取待转换的16进制字符串
        tmp_buf[0] = src[i];
        tmp_buf[1] = src[i + 1];
        tmp_buf[2] = '\0'; // 记得添加空字符
        // 转换成16进制,base传16即可
        dest[j++] = strtol(tmp_buf, &endptr, 16);
    }

    dest[j] = '\0'; // 添加字符串结束符

    return j;
}

int len = hex\_str\_2\_str(res, data);

printf("len: %d, str: %s", len, res); // len: 15, str: Hello World!!

字符串转16进制字符串

前面介绍了16进制字符串转字符串,那现在我们来试试如何反过来转换。具体操作是依次将每个字符拿到并转换成对应的16进制,然后再以字符串的形式储存在容器中即可。

在这里我们需要用到库函数sprintf(),其函数声明为int sprintf(char *str, const char *format, ...),该函数是把格式化输出内容发送到所指向的字符串str中。

  1. 参数:

    • str – 指向一个字符数组的指针,该数组存储了C字符串
    • format – 这是字符串,包含了要被写入到字符串str的文本。它可以包含嵌入的format标签,format标签可被随后的附加参数中指定的值替换,并按需求进行格式化
  2. 返回值:
    如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。

具体操作如下示例:

#include "stdio.h" // sprintf()函数声明所在的头文件
char data[] = "Hello World!!\r\n";
char res[32];

int str\_2\_hex\_str(char \*dest, char \*src)
{
    int len = strlen(src); // 获取接收数据长度
    int i,j;

    for (i = 0, j = 0; i < len; i++) {
    	// %02X: 是格式化字符串,意思是以大写的形式(通过X大小写控制)转换成16进制,长度不足2的自动补0
        sprintf(&dest[j], "%02X", src[i]);
        j+=2; // 每个16进制占2个长度
    }

    dest[j] = '\0'; // 添加字符串结束符

## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/bdb5d23d0abcb71887d4129fbf87bf0f.png)

![img](https://img-blog.csdnimg.cn/img_convert/cb5da415605cc4c5b171d11be55e876f.jpeg)

![img](https://img-blog.csdnimg.cn/img_convert/3ffb0df0a95392b1a0b12f9dd7110573.png)

 ![img](https://img-blog.csdnimg.cn/img_convert/532bafdb75ef61babbb6ed185b7a06cb.png)

![img](https://img-blog.csdnimg.cn/img_convert/b8fd877149a5480d6a0bdca3962f665b.png)

![img](https://img-blog.csdnimg.cn/img_convert/828795bc2f2a1b4ac444f9ce281f1ad1.png)

![](https://img-blog.csdnimg.cn/img_convert/ceaee79e004f4deeaa8a0efe450f17c1.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!


**](https://bbs.csdn.net/topics/618654289)

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!


  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值