tabla pantalla imprimir hexadecimal especiales dev como codigo caracteres c hex printf

pantalla - imprimir hexadecimal en c



Imprimir caracteres hexadecimales en C (7)

De hecho, hay conversión de tipo a int. También puede forzar el tipo a char usando el especificador% hhx.

printf("%hhX", a);

Intento leer en una línea de caracteres y luego imprimir el equivalente hexadecimal de los caracteres.

Por ejemplo, si tengo una cadena que es "0xc0 0xc0 abc123" , donde los primeros 2 caracteres son c0 en hexadecimal y los caracteres restantes son abc123 en ASCII, entonces debería obtener

c0 c0 61 62 63 31 32 33

Sin embargo, printf usando %x me da

ffffffc0 ffffffc0 61 62 63 31 32 33

¿Cómo obtengo el resultado que quiero sin el "ffffff" ? ¿Y por qué es que solo c0 (y 80) tiene el ffffff , pero no los otros personajes?


Estás viendo el ffffff porque char está ffffff en tu sistema. En C, las funciones vararg como printf promoverán todos los enteros más pequeños que int a int . Como char es un entero (entero con signo de 8 bits en su caso), sus caracteres se están promoviendo a int través de la extensión de signo.

Como c0 y 80 tienen un valor de 1 bit (y son negativos como un número entero de 8 bits), se están extendiendo los signos, mientras que los otros en la muestra no lo hacen.

char int c0 -> ffffffc0 80 -> ffffff80 61 -> 00000061

Aquí hay una solución:

char ch = 0xC0; printf("%x", ch & 0xff);

Esto enmascara los bits superiores y conserva solo los 8 bits más bajos que desee.


Probablemente esté almacenando el valor 0xc0 en una variable char , lo que probablemente sea un tipo firmado, y su valor sea negativo (el conjunto de bits más significativo). Luego, al imprimir, se convierte a int , y para mantener la equivalencia semántica, el compilador rellena los bytes adicionales con 0xff, por lo que el int negativo tendrá el mismo valor numérico de su char negativo. Para solucionar esto, solo envía a unsigned char al imprimir:

printf("%x", (unsigned char)variable);


Probablemente esté imprimiendo desde una matriz de caracteres firmada. Imprima desde una matriz de caracteres sin signo o enmascare el valor con 0xff: por ejemplo, ar [i] y 0xFF. Los valores de c0 se están extendiendo por signo porque se establece el bit alto (signo).


Pruebe algo como esto:

int main() { printf("%x %x %x %x %x %x %x %x/n", 0xC0, 0xC0, 0x61, 0x62, 0x63, 0x31, 0x32, 0x33); }

Que produce esto:

$ ./foo c0 c0 61 62 63 31 32 33


Puede crear un char sin signo:

unsigned char c = 0xc5;

Imprimirlo dará C5 y no ffffffc5 .

Solo los caracteres más grandes que 127 se imprimen con el ffffff porque son negativos (el carácter está firmado).

O puede lanzar el char mientras imprime:

char c = 0xc5; printf("%x", (unsigned char)c);


Puede usar hh para decirle a printf que el argumento es un char sin signo. Use 0 para obtener relleno cero y 2 para establecer el ancho a 2. x X para caracteres hexadecimales de mayúscula / minúscula.

uint8_t a = 0x0a; printf("%02hhX", a); // Prints "0A" printf("0x%02hhx", a); // Prints "0x0a"

Editar : si a los lectores les preocupa la afirmación de 2501 de que, de alguna manera, no se trata de los especificadores de formato "correctos", sugiero que vuelvan a leer el printf . Específicamente:

Aunque% c espera el argumento int, es seguro pasar un char debido a la promoción entera que tiene lugar cuando se llama a una función variadic.

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. son sinónimos 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 firmado. No hay ningún especificador de formato hexideximal firmado de todos modos.

Edición 2 : ( edición de "cuándo admitir que estás equivocado"):

Si lee el estándar C11 real en la página 311 (329 del PDF), encontrará:

hh: especifica que el siguiente especificador de conversión d , i , o , u , x o X aplica a un argumento unsigned char o unsigned char (el argumento se habrá promocionado de acuerdo con las promociones enteras, pero su valor se convertirá en signed char o signed char unsigned char antes de imprimir); o que un especificador de conversión n siguiente se aplica a un puntero a un argumento signed char .