0

我正在尝试将十六进制格式的 char[] 转换为十六进制的 int[]。

像这样的东西:

你好 --> 68656C6C6F --> [68, 65, 6C, 6C, 6F]

这是我的代码:

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

uint8_t* hex_decode(unsigned char *in, size_t len, uint8_t *out);

int main(void){
unsigned char  word_in[17], word_out[33];//17:16+1, 33:16*2+1
int i, len = 0;
uint8_t* out;


while(len != 16){
    printf("Set new word:");
    fgets( word_in, sizeof( word_in), stdin);
    len = strlen( word_in);
    if( word_in[len-1]=='\n')
        word_in[--len] = '\0';

    for(i = 0; i<len; i++){
        sprintf(word_out+i*2, "%02X",  word_in[i]);
    }
    if(len != 16){
        printf("Please, use a word of 16 chars long\n\n");
    }
}
printf("%s", word_in);
printf("\n");

hex_decode(word_out, sizeof(word_out), out);

return 0;
}

uint8_t* hex_decode(unsigned char *in, size_t len, uint8_t *out)
{
    unsigned int i, t, hn, ln;

    for (t = 0,i = 0; i < len; i+=2,++t) {

            hn = in[i] > '9' ? (in[i]|32) - 'a' + 10 : in[i] - '0';
            ln = in[i+1] > '9' ? (in[i+1]|32) - 'a' + 10 : in[i+1] - '0';

            out[t] = (hn << 4 ) | ln;
            printf("%s",out[t]);
    }
    return out;

}

但是在打印这个词之后,我得到了一个分段错误。

该功能在arduino中运行完美,所以我认为它应该在我的计算机上运行良好......问题出在哪里?

4

5 回答 5

1

您会遇到分段错误,因为您在对其out进行任何分配之前传递了指针。要么hex_decode需要获取uint8_t **out_ptr并为其分配一个动态分配的数组,要么调用者需要提供一个足以容纳转换输出的数组。

它在另一个平台上“工作”的原因是它表现出未定义的行为:在 arduino 中,放置在未初始化指针中的任意值out恰好指向内存中未使用的位置。写入该位置不会触发分段错误,从而产生工作代码的错觉。

于 2013-05-13T17:07:14.270 回答
1

有关段错误,请参阅@dasblinkenlight 答案。解码 2 个字节:

我的 50 C ent...(短版)

char hex[3];
char * phex;
int result;
for(int i = 0; i < 256; i++)
{
    sprintf(hex, "%02X", i);
    phex = hex;
    result = ((*phex > 64 ? (*phex & 0x7) + 9 : *phex - 48) << 4) | (*(phex+1) > 64 ? (*(phex+1) & 0x7) + 9 : *(phex+1) - 48);
    if(result != i)
    {
        printf("err %s %02X\n", hex, result);
    }
}

上面的代码没有验证。当输入无效时,此过程返回 -1。

int h2i(char * ph)
{
    int result;
    if(*ph > 96 && *ph < 103) result = *ph - 87;
    else if(*ph > 64 && *ph < 71) result = *ph - 55;
    else if(*ph > 47 && *ph < 59) result = *ph - 48;
    else return -1;
    result <<= 4;
    ph++;
    if(*ph > 96 && *ph < 103) result |= *ph - 87;
    else if(*ph > 64 && *ph < 71) result |= *ph - 55;
    else if(*ph > 47 && *ph < 59) result |= *ph - 48;
    else return -1;
    return result;
}

可是等等?char 也可以是 -1。是的,在铸造之后。

char * x = "FF";
char y;
int result;
result = h2i(x);
// if (result == -1) ...error...
y = (char)result;
于 2015-05-29T10:06:56.533 回答
0

与您要执行的操作相比,该程序看起来很复杂。

如果你想打印一个字符的十六进制 ascii 代码,你可以简单地使用

printf("%02X",'K'); // this will display the code ascii of 'K' in hexadecimal

如果您想在另一个字符数组中以代码 ascii 打印您的单词。你可以使用sprintf()

int main() {
        char word_in[17]="hello", word_out[33];
        char *pi = word_in, *po = word_out;
        word_out[0]=0;

        for (;*pi;po+=2,pi++)
           sprintf(po,"%02X",*pi);

        printf("%s\n", word_out);
}

一个字符以二进制格式保存在内存中。这种二进制格式表示字符的代码 ascii。当你想打印它的内容时:

  • 使用时"%d":这会将代码 ascii 打印为整数
  • 使用时"%x":这会将代码 ascii 打印为十六进制
  • 使用时"%c":这将打印字符
于 2013-05-13T17:11:32.857 回答
0

我将为此分享我自己的代码:

它将任何 8 个十六进制字符字符串转换为 [-2147483648. 2147483647] 输入(参数)是 1 个字符串(8+'\0'),输出(返回)是一个长整数,根据需要修改

#define N 8

long int hex2dec(char* hex){        /*conversor HEX 2 DEC*/
    int i,j,n[N],l,neg;
    long int dec=0;

    for(i=0;i<N;i++){
        n[i]=0;
    }
    l=strlen(hex);

    neg=0;
    if(hex[0]>='8'){
        neg=1;
        for(i=0;i<N;i++){
            if(hex[i]=='0'){
                hex[i]='F';
                continue;
            }
            if(hex[i]=='1'){
                hex[i]='E';
                continue;
            }
            if(hex[i]=='2'){
                hex[i]='D';
                continue;
            }
            if(hex[i]=='3'){
                hex[i]='C';
                continue;
            }
            if(hex[i]=='4'){
                hex[i]='B';
                continue;
            }
            if(hex[i]=='5'){
                hex[i]='A';
                continue;
            }
            if(hex[i]=='6'){
                hex[i]='9';
                continue;
            }
            if(hex[i]=='7'){
                hex[i]='8';
                continue;
            }
            if(hex[i]=='8'){
                hex[i]='7';
                continue;
            }
            if(hex[i]=='9'){
                hex[i]='6';
                continue;
            }
            if(hex[i]=='A'){
                hex[i]='5';
                continue;
            }
            if(hex[i]=='B'){
                hex[i]='4';
                continue;
            }
            if(hex[i]=='C'){
                hex[i]='3';
                continue;
            }
            if(hex[i]=='D'){
                hex[i]='2';
                continue;
            }
            if(hex[i]=='E'){
                hex[i]='1';
                continue;
            }
            if(hex[i]=='F'){
                hex[i]='0';
                continue;
            }
        }
    }

    for(i=0;i<N;i++){
        switch(hex[i]){
        case '0':
            n[i]=hex[i]-48;  /* Ascii '0'=48 48-48=0*/
            break;
        case '1':
            n[i]=hex[i]-48;  /* Ascii '1'=49 49-48=1*/
            break;
        case '2':
            n[i]=hex[i]-48;
            break;
        case '3':
            n[i]=hex[i]-48;
            break;
        case '4':
            n[i]=hex[i]-48;
            break;
        case '5':
            n[i]=hex[i]-48;
            break;
        case '6':
            n[i]=hex[i]-48;
            break;
        case '7':
            n[i]=hex[i]-48;
            break;
        case '8':
            n[i]=hex[i]-48;
            break;
        case '9':
            n[i]=hex[i]-48;
            break;
        case 'A':
            n[i]=hex[i]-55;  /* Ascii 'A'=65 65-55=10*/
            break;
        case 'B':
            n[i]=hex[i]-55;  /* Ascii 'B'=66 66-55=11*/
            break;
        case 'C':
            n[i]=hex[i]-55;
            break;
        case 'D':
            n[i]=hex[i]-55;
            break;
        case 'E':
            n[i]=hex[i]-55;
            break;
        case 'F':
            n[i]=hex[i]-55;
            break;
        }
    }
    for(i=0,j=l;i<l;i++,j--){
        dec=dec+(n[j-1]*pow(16,i));
    }
    if(neg==1){
        dec=0-dec;
        dec=dec-1;
    }
    return dec;

}
于 2013-05-13T17:20:55.933 回答
0

改变

uint8_t *out;//region is not ensured

uint8_t out[sizeof(word_out)/2];

改变

hex_decode(word_out, sizeof(word_out), out);//sizeof(word_out) is 33, must to 32

hex_decode(word_out, strlen(word_out), out);//strlen(word_out) or len * 2 or sizeof(word_out) -1

改变

printf("%s",out[t]);//out is not string

printf("%02X ",out[t]);
于 2013-05-13T22:10:36.327 回答