首页 > 解决方案 > 将十六进制字符串转换为 ASCII 值的函数导致段错误

问题描述

我正在尝试修改此答案中的代码

https://stackoverflow.com/a/5403170/3657941

所以我有一个函数可以将十六进制字符串转换为存储在输出缓冲区中的 ASCII 值。

我尝试使用snprintf,但出现分段错误。在 GDB 我得到

st=error reading variable: Cannot access memory at address 0x726f6445>
out=error reading variable: Cannot access memory at address 0x726f6441>

这是我的代码:

#include <stdio.h>
#include <string.h>

int hex_to_int(char c)
{
    if (c >= 97)
        c = c - 32;
    int first = c / 16 - 3;
    int second = c % 16;
    int result = first * 10 + second;
    if (result > 9) result--;
    return result;
}

int hex_to_ascii(char c, char d){
        int high = hex_to_int(c) * 16;
        int low = hex_to_int(d);
        return high+low;
}

void hs(const char *st, char *out)
{
        //const char* st = "6665646F7261";
        int length = strlen(st);
        int i;
        char buf = 0;
        int offset = 0;

        for(i = 0; i < length; i++){
                if(i % 2 != 0){
                        //printf("%c", hex_to_ascii(buf, st[i]));

                        offset += snprintf(out + offset, 255 - offset, ":%c", hex_to_ascii(buf, st[i]));
                }else{
                        buf = st[i];
                }
        }

}

int main(){

        char str;
        hs("6665646F7261",&str);
        printf("%c\n", str);
}

我希望以hs十六进制发送函数输入“6665646F7261”并取回“fedora”中的 ASCII 值。

标签: c

解决方案


这会将十六进制对转换为 ASCII 值并将它们存储在缓冲区中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define TARGET_SIZE(input) \
    ((strlen(input) / 2) + 1)

void convert(char *buffer, char *input) {
    // This version is a little better but we still rely on the caller
    // to give us a large enough buffer
    char storage[3];
    int offset = 0;
    assert(strlen(input) % 2 == 0);
    for (int index = 0; index < strlen(input); index+= 2) {
        storage[0] = input[index];
        storage[1] = input[index + 1];
        storage[2] = 0;
        // Now we handle upper and lower case hex values
        buffer[offset] = strtoul(storage, NULL, 16);
        offset++;
    }
    buffer[offset] = 0;
}

int main(void) {
    char fedora[] = "6665646F7261";
    char buffer[TARGET_SIZE(fedora)];
    convert(buffer, fedora);
    printf("%s\n", buffer);
    return 0;
}

输出

fedora

推荐阅读