Puede usar hhpara saber printfque el argumento es un carácter sin firmar. Úselo 0para obtener relleno de cero y 2para establecer el ancho en 2. xo Xpara caracteres hexadecimales en minúsculas / mayúsculas.
uint8_t a = 0x0a;
printf("%02hhX", a); // Prints "0A"
printf("0x%02hhx", a); // Prints "0x0a"
Editar : Si los lectores están preocupados por la afirmación de 2501 de que de alguna manera no son los especificadores de formato "correctos", sugiero que lean el printfenlace nuevamente. Específicamente:
Aunque% c espera un argumento int, es seguro pasar un char debido a la promoción de enteros que tiene lugar cuando se llama a una función variada.
Las especificaciones de conversión correctas para los tipos de caracteres de ancho fijo (int8_t, etc.) se definen en el encabezado <cinttypes>(C ++) o <inttypes.h>(C) (aunque PRIdMAX, PRIuMAX, etc. es sinónimo de% jd,% ju, etc.) .
En cuanto a su punto sobre firmado vs no firmado, en este caso no importa ya que los valores siempre deben ser positivos y encajar fácilmente en un int con signo. De todos modos, no hay un especificador de formato hexadecimal firmado.
Edición 2 : ( edición "cuándo-admitir-que-está-equivocado"):
Si lee el estándar C11 actual en la página 311 (329 del PDF), encontrará:
hh: Especifica que un siguiente d, i, o, u, x, o Xespecificador de conversión se aplica a una signed charo unsigned charargumento (el argumento se habrá promovido de acuerdo con las promociones de enteros, pero su valor se convierte en signed charo unsigned charantes de la impresión); o que un nespecificador de conversión siguiente se aplica a un puntero a un signed charargumento.
"\xc0\xc0abc123"