2010-08-24 7 views
28

pixel_data es un vector de char.¿Por qué printf no imprime solo un byte al imprimir hexadecimal?

Cuando lo hago printf(" 0x%1x ", pixel_data[0]) Estoy esperando ver 0xf5.

Pero obtengo 0xfffffff5 como si estuviera imprimiendo un entero de 4 bytes en lugar de 1 byte.

¿Por qué es esto? He dado printf un char para imprimir, es solo 1 byte, entonces ¿por qué está imprimiendo printf 4?

NB. La implementación de printf está incluida dentro de una API de terceros, pero me pregunto si esta es una característica del estándar printf.

+2

Ver también: http://stackoverflow.com/questions/3512749/memcpy-adds-ff-ff-ff-to-the-beginning-of-a-byte –

Respuesta

48

Probablemente se esté recibiendo una forma benigna de comportamiento indefinido debido a que el modificador %x espera un parámetro unsigned int y una char por lo general se promovió a un int cuando se pasa a una varargs función.

Usted debe convertir explícitamente el char a un unsigned int para obtener resultados predecibles:

printf(" 0x%1x ", (unsigned)pixel_data[0]); 

Tenga en cuenta que un campo ancho de uno no es muy útil. Simplemente especifica el número mínimo de dígitos para mostrar y, en cualquier caso, se necesitará al menos un dígito.

Si char en su plataforma está firmado, esta conversión se convertirán char valores negativos a grandes unsigned int valores (por ejemplo fffffff5). Si desea tratar los valores de bytes como valores sin firmar y simplemente extender cero al convertir a unsigned int, debe usar unsigned char para pixel_data, o enviarlos a través de unsigned char o utilizar una operación de enmascaramiento después de la promoción.

p. Ej.

printf(" 0x%x ", (unsigned)(unsigned char)pixel_data[0]); 

o

printf(" 0x%x ", (unsigned)pixel_data[0] & 0xffU); 
+0

@charles. ¡Gracias por la explicación de por qué los primeros 'f''s! La API de terceros que estoy usando tiene el tipo 'unsigned char', así que cambié mi definición de' pixel_data' para usar esto y obtener los resultados que necesito. – BeeBand

+1

@BeeBand: tenga cuidado, simplemente cambiar a 'char sin signo 'puede no ser suficiente. En la mayoría de las plataformas '' unsigned char' promoverá '' int', not 'unsigned int'. –

+0

@Charles - cuando no cambio a 'unsigned char' y solo hago el reparto, sigo obteniendo las f's principales. Supongo que necesito cambiar a 'unsigned int' y usar una máscara de bits para asegurarme de que funciona en todas las plataformas. – BeeBand

3

Entonces el modificador length es la longitud mínima.

+0

por lo 1 es la longitud mínima? Pensé que el modificador de longitud estaba en bytes. – BeeBand

+3

Es la longitud en caracteres. – leppie

+0

Lo siento, simplemente no entiendo lo que quieres decir. ¿Por qué lo que sucedió implica que el modificador 'length' es la longitud mínima? – BeeBand

2

El especificador de ancho en printf es en realidad de ancho mínimo. Puede hacer printf(" 0x%2x ", pixel_data[0] & 0xff) para imprimir lowes byte (aviso 2, para realmente imprimir dos caracteres si pixel_data[0] es, por ejemplo,).

7

Un mejor uso de los estándares de formato-flags

printf(" %#1x ", pixel_data[0]); 

entonces su compilador pone el hexágono-prefijo para usted.

+0

¡fantástico! por no saber esto, utilicé depurador ... – Tebe

3

Uso %hhx

printf("%#04hhx ", foo); 
+0

lamentablemente estoy usando una implementación de API de terceros de 'printf' que no parece permitir el formateador' hh'. Pero es bueno saberlo, gracias. – BeeBand

Cuestiones relacionadas