Use printf to print character string in hexadecimal format, distorted results

Here's a small program that illustrates the problem I think you might be having:

#include <stdio.h>
int main(void) {
    char arr[] = { 0, 16, 127, 128, 255 };
    for (int i = 0; i < sizeof arr; i ++) {
        printf(" %2x", arr[i]);
    }
    putchar('\n');
    return 0;
}

On my system (on which plain char is signed), I get this output:

  0 10 7f ffffff80 ffffffff

The value 255, when stored in a (signed) char, is stored as -1. In the printf call, it's promoted to (signed) int -- but the "%2x" format tells printf to treat it as an unsigned int, so it displays fffffffff.

Make sure that your mesg and mesg_check arrays are defined as arrays of unsigned char, not plain char.

UPDATE: Rereading this answer more than a year later, I realize it's not quite correct. Here's a program that works correctly on my system, and will almost certainly work on any reasonable system:

#include <stdio.h>
int main(void) {
    unsigned char arr[] = { 0, 16, 127, 128, 255 };
    for (int i = 0; i < sizeof arr; i ++) {
        printf(" %02x", arr[i]);
    }
    putchar('\n');
    return 0;
}

The output is:

 00 10 7f 80 ff

An argument of type unsigned char is promoted to (signed) int (assuming that int can hold all values of type unsigned char, i.e., INT_MAX >= UCHAR_MAX, which is the case on practically all systems). So the argument arr[i] is promoted to int, while the " %02x" format requires an argument of type unsigned int.

The C standard strongly implies, but doesn't quite state directly, that arguments of corresponding signed and unsigned types are interchangeable as long as they're within the range of both types -- which is the case here.

To be completely correct, you need to ensure that the argument is actually of type unsigned int:

printf("%02x", (unsigned)arr[i]);

Tags:

C

Printf