我需要像这样转换十六进制编码的字符串:
char hstr[9] = "61626364"; // characters abcd\0
进入
"abcd" // characters as hex: 0x61 0x62 0x63 0x64
// hex "digits" a-f are always lowercase
此时我写了这个函数:
#include <stdlib.h>
void htostr(char* hexstr, char* str) {
int len = strlen(hexstr);
for (int i = 0; i < len/2; i++) // edit: fixed bounds
{
char input[3] = { hexstr[2 * i], hexstr[2 * i + 1], 0 };
*(str + i) = (char)strtol(input, NULL, 16);
}
}
我正在使用 strtol
函数来完成这项工作。
我觉得我浪费了 3 个字节的内存用于 input
数组,并浪费了一些处理器时间来复制两个字节并以 0 终止,因为 strtol
函数没有像这样的参数“长度”。
代码应该在非常繁忙的微 Controller 上运行,字符串相当长(尽快释放 hexstr
使用的内存是个好主意)。
问题是:是否有更有效的方法来做到这一点,而无需从头开始编写自己的转换器?
“从头开始”是指不使用函数标准库的低级转换。
最佳答案
您可以创建一个函数来转换字符 0
.. 9
和 A,而不是复制两个字符并使用
.. strtol
F
到 int
(0x0
到 0xF
)。
#include <ctype.h>
int toval(char ch) {
if (isdigit((unsigned char)ch)) return ch - '0';
return toupper((unsigned char)ch) - 'A' + 0x10;
}
然后循环字符串并将结果相加将非常简单:
void htostr(char *wr, const char *rd) {
for (; rd[0] != '\0' && rd[1] != '\0'; rd += 2, ++wr) {
// multiply the first with 0x10 and add the value of the second
*wr = toval(rd[0]) * 0x10 + toval(rd[1]);
}
*wr = '\0'; // null terminate
}
使用示例:
#include <stdio.h>
int main() {
char hstr[] = "61626364";
char res[1 + sizeof hstr / 2];
htostr(res, hstr);
printf(">%s<\n", res);
}
关于c - 如何有效地将十六进制编码的字符串转换为 C 中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71564705/