当前位置:首页 » 《随便一记》 » 正文

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

17 人参与  2024年02月20日 18:26  分类 : 《随便一记》  评论

点击全文阅读


平时我们在写功能需求时,难免不会遇到需要将16进制字符串转换成字符串,或者字符串转16进制字符串的需求,所以就有了这篇文章。

在进入主题之前,我们先来回顾一下字符和16进制的关系。我们知道正常的16进制数值(像0x32)和ASIIC码(0x32对应字符2)之间是互通的,即如果你输出数值,就是输出的字符的数值(例如,字符0,十进制就是48),如果你输出字符,那就是输出的字符,不会进行转换(例如,字符0,输出就是字符0),具体可以看下面示例:

char ch = '0';int i = 48;printf("int: %d", ch); // 输出: int: 48printf("char: %c", ch); // 输出: char: 0printf("int: %d", i); // 输出: int: 48printf("char: %c", i); // 输出: char: 0

16进制字符串转字符串

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

参数: str – 要转换为长整数的字符串endptr – 对类型为char*的对象的引用,其值由函数设置为str中数值后的下一个字符base – 基数,必须介于236(包含)之间,或者特殊值0。如果base0,则会根据字符串的前缀来判断进制 返回值:
函数返回被转换的长整型整数值。如果输入字符串不符合数字格式,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中。

参数:

str – 指向一个字符数组的指针,该数组存储了C字符串format – 这是字符串,包含了要被写入到字符串str的文本。它可以包含嵌入的format标签,format标签可被随后的附加参数中指定的值替换,并按需求进行格式化

返回值:
如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。

具体操作如下示例:

#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'; // 添加字符串结束符    return j; // 返回字符串长度}int len = str_2_hex_str(res, data);printf("len: %d, hex: %s", len, res); // len: 30, hex: 48656C6C6F20576F726C6421210D0A

总结

要想实现16进制字符串和字符串之间的相互转换,只要用好strtol()sprintf()这两个库函数,就可以轻松解决

参考

https://www.runoob.com/cprogramming/c-function-strtol.html
https://www.runoob.com/cprogramming/c-function-sprintf.html

关注公众号《嵌入式从入门到放弃》了解更多知识


点击全文阅读


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

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

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

最新文章

  • 半堂花夜渡空城免费在线(裴砚泽沈诺柠)_半堂花夜渡空城免费在线
  • 大雁南飞人不归结局+番外优质全章(姜曼殊沈砚之)_大雁南飞人不归结局+番外优质全章姜曼殊沈砚之
  • [绿茶室友邀请我参加祭祖仪式,却不知我是老祖]人物羁绊章节精选_李岚老祖宗苏婧节选免费试读
  • (番外)+(全书)兰因絮果,爱恨全如玉碎+后续+结局(长乐肖风行)全书在线_兰因絮果,爱恨全如玉碎+后续+结局免费列表_笔趣阁(长乐肖风行)
  • 完结文被绿茶养女夺走真千金身份后,我杀疯了列表_完结文被绿茶养女夺走真千金身份后,我杀疯了(苏楠苏意安+)
  • 刹那芳华顾,褚墨景迟文月+番外+后续_刹那芳华顾,褚墨景迟文月+番外+后续列表
  • 被瘾症折磨的可怜校花免费结局+后续(张团团仁川)全书免费_(张团团仁川)被瘾症折磨的可怜校花免费结局+后续后续(张团团仁川)
  • [竹马率十万铁骑娶我,只为给心上人做嫁衣]反转剧情试读片段_尚书府限免完整章节合集‌
  • 方沐筱宋安(重生后,我将兼挑两房的老公一锅端+后续+结局)结局_(方沐筱宋安重生后,我将兼挑两房的老公一锅端+后续+结局全书结局)结局列表_笔趣阁(方沐筱宋安)
  • 苏浅歌沈廷淮(苏浅歌沈廷淮结局+番外+后续)_苏浅歌沈廷淮列表_笔趣阁(苏浅歌沈廷淮结局+番外+后续)
  • 被瘾症折磨的可怜校花结局+番外(张团团仁川)_(离婚后前夫对婚我念念不忘结局+番外)被瘾症折磨的可怜校花结局+番外列表_笔趣阁(张团团仁川)
  • 一觉醒来发现自己变成了前男友(沈季+)全书浏览_一觉醒来发现自己变成了前男友全书浏览

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

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