Barals
Barals

Reputation: 109

Convert char* in hex to normal char*?

i have this function:

char *ctohex(char *str){
    int i=0, len;
    len = strlen(str);
    char *final = malloc(len*2*sizeof(char)+1);
    while(len--){
         sprintf(final+i*2, "%02X", str[i]);
         i++;
    }
    return final;
}

Now i want a reverse function, from hex to normal char, is that possible? Sorry for my english.No one gives me a good answer, maybe i explained wrong.

I have this input at my function: JOAO output is: 4A4F414F

I want to put 4A4F414F back to JOAO.

Upvotes: 0

Views: 203

Answers (4)

chux
chux

Reputation: 153592

Pretty much a simple reverse of the original ctohex()

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

char *hextoc(const char *str) {
  size_t i, j, len;
  len = strlen(str);

  // If the length is not even
  if (len % 2)
    return NULL;

  char *final = malloc(len/2 + 1);
  if (final == NULL)
    return NULL;

  j = 0;
  for (i = 0; i < len; i += 2) {
    if (!isxdigit((unsigned char) str[i])
            || !isxdigit((unsigned char) str[i+1])) {
      free(final);
      return NULL;
    }
    unsigned x;
    sscanf(&str[i], "%2X", &x);
    final[j++] = (char) x;
  }
  final[j] = '\0';
  return final;
}

int main() {
  return puts(hextoc("4A4F414F"));
  // prints JOAO
}

ctohex(char *str) has a problem. when str[i] is < 0

// sprintf(final+i*2, "%02X", str[i]);
sprintf(final+i*2, "%02X", str[i] & 0xFF);
// or
sprintf(final+i*2, "%02hhX", str[i]);  // Current C compilers

Upvotes: 1

JonS
JonS

Reputation: 651

Your main issue is that you your conversion to hex isn't really doing anything, as you are converting each digit to its hex equivalent, which does nothing. 5 in decimal is also 5 in hex. All you did is put 0's between each digit ("5432" -> "05040302")

If you are asking to take a number in a string that is represented by its hex value and put it into a string as its decimal value, e.g. "0x5A8C" -> "23180", then this is what you do:

    char *convert( char * instr )
    {
        char outstr[50] = {0};
        int tmpval = 0;
        sscanf( instr, "%x", tmpval );
        sprintf( outstr, "%d", tmpval );
        char * retval;
        strcpy( retval, outstr );
        return retval;
    }

The benefit of using sscanf() is that sscanf will treat 0x5a, 0X5A, 5a, and 5A the same.

If you are just trying to convert back any string that is generated by your ctohex() function, then you just need to copy every other digit into a new string.

If you want to convert a sequence of hex digits into decimal values, then you have to specify how many digits are getting converted. Do you want "5A8C" -> "510812" or do you want "90140"?

Upvotes: 0

Yasser Asmi
Yasser Asmi

Reputation: 1170

Use strtol() with base=16 on each of your hex numbers

Upvotes: 0

pmg
pmg

Reputation: 108938

Of course converting from hex to normal char is possible.

Examine 2 characters at a time and decide what char to print

if (char1 == '0' && char2 == '0') putchar(0x00);
if (char1 == '0' && char2 == '1') putchar(0x01);
/* ... */
if (char1 == '4' && char2 == '2') putchar(0x42); /* ASCII B */
/* ... */
if (char1 == 'f' && char2 == 'f') putchar(0xff);

There are more efficicent ways to do it though :)

Upvotes: 0

Related Questions