Home > Blockchain >  How to turn non-printable characters into their hex values in C?
How to turn non-printable characters into their hex values in C?

Time:10-01

I'm trying to make a function that takes an array of characters as an input, and outputs printable characters normally, and non-printable characters in hexadecimal (by turning these character into decimal using Extended ASCII, then turning that decimal number into hex). For example:

"This morning is ßright"

should turn into:

"This morning is E1right"

since ß in Extended ASCII is 225, and that in hexadecimal is E1.

Here is what I attempted:

void myfunction(char *str)
{
    int size=0;
    for (int i = 0; str[i] != NULL; i  ) size  ; //to identify how many characters are in the string
    for (int i = 0; i < size; i  )
    {
        if (isprint(str[i]))
        {
            printf("%c", str[i]); //printing printable characters
        }
        else
        {
            if (str[i] == NULL) break; //to stop when reaching the end of the string
            printf("x", str[i]);  //This is where I'm having an issue     
        }
    } 
}

This function outputs this:

"This morning is ffffffc3ffffff9fright"

how can I turn the non-printable characters into their hex value? and what is causing this function to behave in this way?

Thanks in advance!

CodePudding user response:

You're seeing a couple of issues here. The first is that the char type on your machine (as on most) is signed, so when you have a char that is not ascii, it shows up as a negative number. This then sign extends to your int size before you print it as an unsigned hex value, so you get those ffffff strings you see.

If you mask it to 8 bits, you'll see the hex values more clearly. Use

printf("X", str[i] & 0xff);  // X to use upper-case hex chars for clarity

and you'll get the output

This morning is C39Fright

Now you see the second problem, which is that ß is not an ascii character. It is unicode character #000DF, however, and when it is encoded in UTF-8 it shows up as the two-byte sequence C3 9F.

CodePudding user response:

You have plenty of issues with your code.

for (int i = 0; str[i] != NULL; i ) size ; NULL is a pointer str[i] is char. You simply want to compare with zero which is a null character. null character is not the same as NULL pointer!!!

Same here: if (str[i] == NULL) break;

printf("x", str[i]); you use wron format to print char value as number. You should use hh size modifier. See how it works in the attached code.

Use the correct type for indexes or sizes - size_t instead of int

Your code is overcomplicated.

void myfunction(const char *str)
{
    while(*str)
    {
        if (isprint(*str))
        {
            printf("%c", *str); //printing printable characters
        }
        else
        {
            printf("hhX", *str);  //This is where I'm having an issue     
        }
        str  ;
    } 
}

int main(void)
{
    char *str = "This morning is \xE1right";

    myfunction(str);
}

https://godbolt.org/z/6jKWdr3rM

  • Related