Qual é o especificador de formato para int curto não assinado?

124

Eu tenho o seguinte 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 quando compilado usando gcc filename.cemitiu o seguinte aviso (na scanf()linha).

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

Em seguida, o referido C99 specification - 7.19.6 Formatted input/output functionse não poderia compreender o especificador de formato correcto quando se utiliza os modificadores de comprimento (como short, long, etc.) com unsignedpara inttipo de dados.

O %uespecificador correto é unsigned short int? Se sim, por que estou recebendo o aviso acima mencionado ?!

Edição: Na maioria das vezes, eu estava tentando %uhe ainda estava dando o aviso.

Sangeeth Saravanaraj
fonte
2
printf("%u\n", (unsigned int)length); //sempre funciona, uma vez que o C99 especificação você lê garante que sizeof(short) <= sizeof(int)(mas as respostas reais a esta pergunta abaixo são, naturalmente, muito mais agradável)
Philip
1
Não há necessidade do elenco; promoções padrão cuidam disso.
R .. GitHub Pare de ajudar o gelo

Respostas:

155

Tente usar o "%h"modificador:

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

ISO / IEC 9899: 201x - 7.21.6.1-7

Especifica que o seguinte especificador de conversão d, i, o, u, x, X ou n se aplica a um argumento com o ponteiro de tipo para curto ou curto não assinado .

cnicutar
fonte
47

Para scanf, você precisa usar %hudesde que você está passando um ponteiro para um unsigned short. Para printf, é impossível passar um unsigned shortpor inadimplência promoções (que será promovido para intou unsigned intdependendo se inttem pelo menos tantos bits de valor, como unsigned shortou não), de modo %dou %uestá bem. Você é livre para usar, %huse preferir.

R .. GitHub PARE DE AJUDAR O GELO
fonte
7

Na página de manual do Linux:

h Uma conversão de número inteiro a seguir corresponde a um argumento int curto ou int curto não assinado ou a um
       A conversão n abaixo corresponde a um ponteiro para um argumento int curto.

Portanto, para imprimir um número inteiro curto não assinado, a string de formato deve ser "%hu".

Algum cara programador
fonte
Eu não acho que é assim que você "imprime" ints curtos, porque eles são automaticamente promovidos para ints (assim como caracteres).
Alexey Frunze
2
@Alex% hu /% hd no printf funciona. Foi% hhu /% hhd que está disponível apenas a partir do C99. % he% hh implicam um resp & 0xFFFF. & 0xFF no número inteiro passado.
Jorgensen