2012-01-02 25 views
90

Tengo el siguiente programa¿Cuál es el especificador de formato para int corto sin signo?

#include <stdio.h> 

int main(void) 
{ 
    unsigned short int length = 10; 

    printf("Enter length : "); 
    scanf("%u", &length); 

    printf("value is %u \n", length); 

    return 0; 
} 

Qué cuando se compila utilizando gcc filename.c el aviso siguiente (en la línea scanf()).

warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat]

entonces remitió el C99 specification - 7.19.6 Formatted input/output functions y no podía entender el especificador de formato correcto utilizando los modificadores de longitud (como short, long, etc) con unsigned para int tipo de datos.

¿Es %u el especificador correcto unsigned short int? Si es así, ¿por qué recibo la advertencia mencionada?

EDITAR: La mayoría de las veces, estaba tratando %uh y todavía estaba dando la advertencia.

+2

'printf ("% u \ n ", longitud (sin signo)); // 'siempre funciona, ya que la especificación C99 que lees garantiza que' sizeof (short) <= sizeof (int) '(pero las respuestas reales a esta pregunta a continuación son, por supuesto, mucho más agradables) – Philip

+1

No hay necesidad del molde; las promociones predeterminadas se encargan de eso. –

Respuesta

118

Trate de usar la "%h" modificador:

scanf("%hu", &length); 
     ^

ISO/IEC 9899: 201x - 7.21.6.1-7

especifica que un siguiente d, i, o, u, x, X o n conversión especificador se aplica a un argumento con el tipo puntero a corto o corto sin signo.

+0

Documentación de origen, por favor? – sergiol

+1

@sergiol Agregué la fuente. – cnicutar

6

Desde la página de manual de Linux:

 
h  A following integer conversion corresponds to a short int or unsigned short int argument, or a fol‐ 
     lowing n conversion corresponds to a pointer to a short int argument. 

Así que para imprimir un entero corto sin signo, la cadena de formato debe ser "%hu".

+0

No creo que así es como "printf" porque es automáticamente promovido a ints (como los caracteres). –

+2

@Alex% hu /% hd en printf funciona. Fue% hhu /% hhd que solo está disponible comenzando con C99. % h y% hh implican un & 0xFFFF resp. & 0xFF en el entero pasado. –

+0

@ jørgensen: tienes razón, está en el estándar. –

36

Para scanf, necesita usar %hu ya que está pasando un puntero a unsigned short. Para printf, es imposible pasar una unsigned short debido a las promociones por defecto (que será promovido a int o unsigned int dependiendo de si int tiene al menos tantos bits como valor unsigned short o no) por lo %d o %u está muy bien. Sin embargo, puedes usar %hu si prefieres.

+6

+1 por mencionar las promociones predeterminadas en 'printf()'. ¡Gracias! –

Cuestiones relacionadas