Reputation: 3833
I am trying to convert a char[] in hexadecimal format to int[] in hexadecimal.
Something like this:
hello --> 68656C6C6F --> [68, 65, 6C, 6C, 6F]
This is my code:
#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;
}
But after printing the word, I got a segmentation fault.
That function works perfect in arduino so I think it should works fine at my computer... Where is the problem?
Upvotes: 0
Views: 2257
Reputation: 455
See @dasblinkenlight answer for seg fault. To decode 2 bytes:
My 50 Cent... (a short version)
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);
}
}
Code above does no validation. This procedure returns -1 when input was invalid.
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;
}
But wait? A char can also be -1. Yes, after casting.
char * x = "FF";
char y;
int result;
result = h2i(x);
// if (result == -1) ...error...
y = (char)result;
Upvotes: 1
Reputation: 43558
The program looks complicated comparing what you want to do.
if you want to print the hexadecimal ascii code of a charachter, you can simply use
printf("%02X",'K'); // this will display the code ascii of 'K' in hexadecimal
If you want to print your word in code ascii in another char array. you can use 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);
}
A charachetr is saved in binary format in the memory. this binary format represent the code ascii of the charachter. And when you want to print its content:
"%d"
: this will print the code ascii as integer"%x"
: this will print the code ascii as hexadecimal"%c"
: this will print the charachterUpvotes: 0
Reputation: 40145
change
uint8_t *out;//region is not ensured
to
uint8_t out[sizeof(word_out)/2];
change
hex_decode(word_out, sizeof(word_out), out);//sizeof(word_out) is 33, must to 32
to
hex_decode(word_out, strlen(word_out), out);//strlen(word_out) or len * 2 or sizeof(word_out) -1
change
printf("%s",out[t]);//out is not string
to
printf("%02X ",out[t]);
Upvotes: 0
Reputation: 625
i will just share my own code for this:
it converts any 8 hexadecimal char string into a integer number from [-2147483648. 2147483647] input(argument) is 1 string(8+'\0'), output(returns) is a long int, MODIFY AS NECESSARY
#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;
}
Upvotes: 0
Reputation: 726967
You get a segmentation fault because you are passing the pointer out
before making any assignments to it. Either the hex_decode
need to take uint8_t **out_ptr
and assign it a dynamically allocated array, or the caller needs to provide an array sufficient to hold the output of the conversion.
The reason why it "works" on another platform is that it exhibits undefined behavior: in arduino, the arbitrary value placed in the uninitialized pointer out
happens to point to an unused location in memory. Writing to that location does not trigger segmentation fault, creating an illusion of working code.
Upvotes: 1