¿Cuál es el especificador de formato para unsigned short int?

124

Tengo el siguiente programa

#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;
}

Que cuando se compila utilizando gcc filename.cemitió la siguiente advertencia (en la scanf()línea).

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

Entonces me he referido al C99 specification - 7.19.6 Formatted input/output functionsy no podía entender el especificador de formato correcto al utilizar los modificadores de longitud (como short, long, etc.) con el unsignedde inttipo de datos.

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

EDITAR: La mayoría de las veces, lo intentaba %uhy todavía daba la advertencia.

Sangeeth Saravanaraj
fuente
2
printf("%u\n", (unsigned int)length); //siempre funciona, ya que la especificación C99 que lees garantiza eso sizeof(short) <= sizeof(int)(pero las respuestas reales a esta pregunta a continuación son, por supuesto, mucho mejores)
Philip
1
No hay necesidad del elenco; las promociones por defecto se encargan de ello.
R .. GitHub DEJA DE AYUDAR A ICE

Respuestas:

155

Intenta usar el "%h"modificador:

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

ISO / IEC 9899: 201x - 7.21.6.1-7

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

cnicutar
fuente
47

Para scanf, debe usar %huya que está pasando un puntero a un unsigned short. Para printf, es imposible pasar un unsigned shortdebido a las promociones predeterminadas (se promocionará a, into unsigned intdependiendo de si inttiene al menos tantos bits de valor como unsigned shorto no), %do %uestá bien. Sin %huembargo, puedes usarlo si lo prefieres.

R .. GitHub DEJA DE AYUDAR AL HIELO
fuente
7

Desde la página del manual de Linux:

h Una siguiente conversión de entero corresponde a un argumento int corto o int corto sin signo, o un siguiente
       lowing n conversion corresponde a un puntero a un argumento int corto.

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

Algún tipo programador
fuente
No creo que así se "impriman" las entradas cortas porque se promocionan automáticamente a entradas (al igual que los caracteres).
Alexey Frunze
2
@Alex% hu /% hd en printf funciona. Era% hhu /% hhd que solo está disponible a partir de C99. % h y% hh implican un & 0xFFFF resp. & 0xFF en el entero pasado.
jørgensen