1

Is there any function that can convert hex char array to an ASCII char array, something like this:

char array_input[] = "48656C6C6F3"; //Input hex sequence
char array_output[] = "Hello";      // Output ASCII

and that can accept input sequences that contain more than 300 letters.

something like:

char array_input[] = "08010000013feb55f000000000000f74000f0ea850209a690000940000120000001e09010002000300040016014703f0001504c8000c0900730a00460b00501300464306d7440000b5000bb60007422e9f180000cd0386ce000107c700000000f10000601a46000001344800000bb84900000bb84a00000bb84c00000000024e0000000000000000cf000001";
1
  • Use any way you know to separate the hex values and convert each of them into a char. Since this is apparently homework, show some effort how to solve this. Commented Dec 3, 2021 at 10:47

2 Answers 2

2

Parse 2 hex digits at a time

Walk the input string looking for 2 hex digits. Form the ASCII value and then append to the output array. Append a final null character.

void foo(char *array_output, const char *array_input) {
  unsigned value;
  while (sscanf(array_input, "%2x", &value) == 1) {
    *array_output++ = value;
    array_input += 2;
  } 
  *array_output = '\0';
}

Pathological strings with white-space or signs like " A12-3" need additional code to handle.


Alternative: use is...() to test for hex digits. Then form a compound literal s to pass to strtol().

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

void foo2(char *array_output, const char *array_input) {
  const unsigned char *h = (const unsigned char *) array_input;
  while (isxdigit(h[0]) && isxdigit(h[1])) {
    char s[3] = { h[0], h[1], '\0' };
    *array_output++ = (char) strtol(s, 0, 16);
    h += 2;
  }
  *array_output = '\0';
}
Sign up to request clarification or add additional context in comments.

3 Comments

You might show how to use %n to handle input strings with embedded spaces gracefully such as "48 65 6C 6C 6F 3", but spaces inside hex digit pairs and embedded + signs would also be ignored, which could be surprising. The input string could also be validated with array_input[strcspn(array_input, "0123456789abcdefABCDEF")] == '\0'
@chqrlie Yes - good idea, yet sscanf() does have more shortcomings (too many). Alternate, more robust isxdigit() posted.
Indeed both sscanf and strtol feel like using a steam hammer to squash a fly :)
2

Here is an efficient alternative solution without any library calls:

void hextostr(char *dest, const char *src) {
    static unsigned char const val[(unsigned char)-1+1] = {
        ['0'] =  0+1, ['1'] =  1+1, ['2'] =  2+1, ['3'] =  3+1, ['4'] =  4+1,
        ['5'] =  5+1, ['6'] =  6+1, ['7'] =  7+1, ['8'] =  8+1, ['9'] =  9+1,
        ['a'] = 10+1, ['b'] = 11+1, ['c'] = 12+1, ['d'] = 13+1, ['e'] = 14+1, ['f'] = 15+1,
        ['A'] = 10+1, ['B'] = 11+1, ['C'] = 12+1, ['D'] = 13+1, ['E'] = 14+1, ['F'] = 15+1,
    };
    const unsigned char *p = (const unsigned char *)src;
    while (val[p[0]] && val[p[1]]) {
        *dest++ = (char)(val[p[0]] * 16 + val[p[1]] - 17);
        p += 2;
    }
    *dest = '\0';
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.