1

I have a char array which contains ASCII characters. I need to know how to get the hex value of each character and save it in a uint8_t array.

E.g. if I have

array[5] = "ABCDE"

The output should be

output[5] = {0x41, 0x42, 0x43, 0x44, 0x45}

I tried using strtol but didn't work.

for(unsigned i = 0; i < 32; i++) {
    message[i] = (uint8_t)strtol(&incoming_message[i], NULL, 16);
}

Output:
A 0 0 0 0 0 0 0 0 0 F 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Update: This is for a program I'm writing for a Cortex-M0+ processor. I'm not just viewing incoming data, I'm processing this data in the next step. Therefore, no use of printf

10
  • 1
    uint8_t can't contain hex values; and "ABCDE" is equivalent to {0x41,0x42,0x43,0x44,0x45,0}. Just cast. (Also as a sidenote, "ABCDE" doesn't fit into array[5], as it has 6 elements, because strings are NUL-terminated, as shown in the equivalent byte array. Commented Aug 1, 2018 at 6:03
  • Yes. That's just an example. But thank you for pointing that out. Commented Aug 1, 2018 at 6:31
  • "ABCDE" is an array of 6 chars as there is added a 0 terminator. I'm not sure whether the compiler complains or implicitly fixes char array[5] = "ABCDE";. However, you may access the first 5 chars. The expected output are already the corresponding ASCII values (as already pointed out) and sizeof (char) == sizeof (uint8_t). So, this can be reduced to a simple copy: memcpy(output, array, 5);. (But, if you can't use memcpy() for any reasons a simple for loop should do as well.) Commented Aug 1, 2018 at 6:49
  • Regarding char array[5] = "ABCDE"; - I checked this out: The compilers (gcc HEAD 9.0.0, clang HEAD 7.0.0, both with -pedantic) don't complain but fixes this implicitly: Test on Wandbox. (Early in the morning but already learned something...) ;-) Commented Aug 1, 2018 at 6:57
  • 2
    @Scheff: array[5] = "ABCDE" is special. It defines (and initialises) a char-array with five elements (only). No 0-terminator here. This is in line with the C11 standard. Commented Aug 1, 2018 at 7:34

3 Answers 3

4

First of all, strtol like all other string functions expects a null-terminated byte string, not single characters.

Secondly, the characters encoded value is the actual value of the elements in your string. If you print the decimal value 65 (for example) using the correct format specifier, then the character A will be printed:

printf("%c\n", 65);  // Will print an A

Similarly, printing the character 'A' as a decimal integer will print the value 65:

printf("%d\n", 'A');  // Will print the value 65

So all you need to do is to print the values in your array in the correct format.


Furthermore... All values on computers the last few decades are stored in binary. All of them.

Decimal, octal or hexadecimal are just how you present the values. Storing 0x41, 61, 0101 or 0b01000001 (for compilers with binary notation extension) doesn't matter since in the end it will be the binary value that is stored. If you want to show a value as hexadecimal to a user through some output, you have to format the binary value as such when printing or writing it.

Sign up to request clarification or add additional context in comments.

5 Comments

I think the OPwants also to save the hexvalues in an uint8_t array as he mentioned.
@Alan Which is really impossible (added note about it).
programmer Saw it, didn't think about it! Cheers.
Thank you for the reply. Sorry forgot to mention, this is for an embedded system. printf is not available for me.
@ADGAN Then you probably use some other method of presenting the values? Because no matter what it's just a presentational issue.
4
  1. Talking C a char is the smallest integer value available.
  2. Talking C and ASCII a character literal (like 'A') is just another representation of an int value (65 here).
  3. Talking Math there are other ways to represent the very same value, aside the decimal way (using base 10). One common is using the base of 16, the hexadecimal way.

Putting the above together it proves that:

int i = 'A';
char c = i; 

is the same as:

int i = 65; 
char c = i; 

and the same as:

int i = 0x41; 
char c = i; 

and the same as:

char c = 'A';

and the same as:

char c = 65;

and the same as:

char c = 0x41;

So

char a[5] = "ABCDE";

in fact already is an integer array of five (small) integers.

If printed using the correct conversion specifier and length modifier you see what you are after.

for (size_t i = 0; i < 5; ++i)
{
  printf("%hhx ", a[i]);
}

Output:

41 42 43 44 45

To indicate to the reader this should be taken as hexadecimal values one could prefix the value using the common 0x notation

  printf("0x%hhx ", a[i]);

which gave you

0x41 0x42 0x43 0x44 0x45

If you would show this to Pascal guys you perhaps would use

  printf("$%hhx ", a[i]);

which gave you

$41 $42 $43 $44 $45

To see the characters themselves just us:

  printf("%c ", a[i]);

and get

A B C D E

To see the decimal values use

  printf("%d ", a[i]);

and get

65 66 67 68 69

The conclusion is, that it's all just matter of how you represent ("print") the same values (the content of a's elements) . The "conversion" happens when creating the representation of a very same value (via printing and passing the right "instructions"), that is during output only.


As you refer to ASCII only, this implies all value are <128, so you can just plain copy the array's values using either a loop

char src[5] = "ABCDE";
uint8_t dst[5];

for (size_t i = 0 i < 5; ++i)
{
  dst[i] = src[i];
}

or by copying the related memory block at once

memcpy(dst, src, 5);

Comments

-1

you can convert the value to hexadecimal using the basic algorithm i.e division by 16. I have created the following function where you can pass the string to be converted and a an array of strings where you will get the response.

void hexCon(char str[],char result[][5]){
    int i,check,rem = 0;
    char res[20],res2[20];        
    int len = 0;    
    char temp;          

    for(i=0; i < strlen(str) ; i++){
        len=0;
        check = str[i];
        while(check > 0){
        rem = check%16;
        switch(rem){
            case 10:temp='A';break;
            case 11:temp='B';break;
            case 12:temp='C';break;
            case 13:temp='D';break;
            case 14:temp='E';break;
            case 15:temp='F';break;
            default:temp=rem + '0';
        }
        res[len] = temp;       
        check = check /16;
        len++;    
    }

    reverse(res,len,res2);  //reversing the digits
    res2[len] = '\0';       //adding null character at the end of string
    strcpy(result[i],res2); //copying all data to result array
    }
}

where reverse function is :

void reverse(char str[], int size, char rev[]) 
{       
    int i=0,j=0;
    for(i=size-1 , j=0 ; i >= 0; i-- , j++ ){
        rev[j] = str[i];
    }    
}

you can call it like :

void main(){    
    char str[]="ABCDE";
    char result[strlen(str)][5];
    int i;
    hexCon(str,result);
    for(i =0 ;i < strlen(str); i++){
        printf("%s\n",result[i]);
    }
}

the algorithm used is explained here :- https://www.permadi.com/tutorial/numDecToHex/

Hope this helps :)

1 Comment

How does this answer the question in its whole?

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.