c - 如何有效地将十六进制编码的字符串转换为 C 中的字符串

标签 c string strtol strtoul

我需要像这样转换十六进制编码的字符串:

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 .. 9A,而不是复制两个字符并使用 strtol .. Fint(0x00xF)。

#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/

相关文章:

string - 如何在 bash 中的两个函数之间传递包含空格的字母数字变量?

c - strtol 重用参数

c - `__heap_base`在clang 9.0.0中好像不见了,有没有替代品?

c++ - 多行预处理器宏

C - Do-while 后跟一个带有 int 案例的 switch。验证不好

django - 如何将 django 模板变量呈现为 html?

c - send() 到特定客户端 C WInSock

C 字符串处理

c - strtol 未按预期工作

c++ - 如何修复 'No matching function for call to ' strtok''