Q:

C/C++ Printing bytes in hex, getting weird hex values

I am using the following to print out numbers from an array in hex:
char buff[1000];

// Populate array....

int i;
for(i = 0; i < 1000; ++i)
{
    printf("[%d] %02x\n", i,buff[i]);
}

but I sometimes print weird values:
byte[280] 00     
byte[281] 00     
byte[282] 0a     
byte[283] fffffff4         // Why is this a different length?
byte[284] 4e      
byte[285] 66      
byte[286] 0a   

Why does this print 'fffffff4'?

A:

Use %02hhx as the format string.
From CppReference, %02x accepts unsigned int. When you pass the arguments to printf(), which is a variadic function, buff[i] is automatically converted to int. Then the format specifier %02x makes printf() interprets the value as int, so potential negative values like (char)-1 get interpreted and printed as (int)-1, which is the cause of what you observed.
It can also be inferred that your platform has signed char type, and a 32-bit int type.
The length modifier hh will tell printf() to interpret whatever supplied as char type, so %hhx is the correct format specifier for unsigned char.
Alternatively, you can cast the data to unsigned char before printing. Like
printf("[%d] %02x\n", i, (unsigned char)buff[i]);

This can also prevent negative values from showing up as too long, as int can (almost) always contain unsigned char value.

See the following example:
#include <stdio.h>

int main(){
    signed char a = +1, b = -1;
    printf("%02x %02x %02hhx %02hhx\n", a, b, a, b);
    return 0;
}

The output of the above program is:
01 ffffffff 01 ff

A:

Your platform apparantly has signed char. On platforms where char is unsigned the output would be f4.
When calling a variadic function any integer argument smaller than int gets promoted to int.
A char value of f4 (-12 as a signed char) has the sign bit set, so when converted to int becomes fffffff4 (still -12 but now as a signed int) in your case.
%x02 causes printf to treat the argument as an unsigned int and will print it using at least 2 hexadecimal digits.
The output doesn't fit in 2 digits, so as many as are required are used.
Hence the output fffffff4.
To fix it, either declare your array unsigned char buff[1000]; or cast the argument:
    printf("[%d] %02x\n", i, (unsigned char)buff[i]);

