Quel est le spécificateur de format pour un int court non signé?

124

J'ai le programme suivant

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

Qui, une fois compilé en utilisant, a gcc filename.cémis l'avertissement suivant (dans la scanf()ligne).

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

Mentionnant la C99 specification - 7.19.6 Formatted input/output functionset ne pouvait pas comprendre le spécificateur de format correct lorsque vous utilisez les modificateurs de longueur (comme short, long, etc.) avec unsignedpour le inttype de données.

Le %uspécificateur est -il correct unsigned short int? Si oui, pourquoi est-ce que je reçois l'avertissement mentionné ci-dessus?!

EDIT: La plupart du temps, j'essayais %uhet cela donnait toujours l'avertissement.

Sangeeth Saravanaraj
la source
2
printf("%u\n", (unsigned int)length); //fonctionne toujours, puisque la spécification C99 que vous lisez garantit que sizeof(short) <= sizeof(int)(mais les réponses réelles à cette question ci-dessous sont bien sûr beaucoup plus agréables)
Philip
1
Pas besoin de plâtre; les promotions par défaut s'en chargent.
R .. GitHub STOP HELPING ICE

Réponses:

155

Essayez d'utiliser le "%h"modificateur:

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

ISO / CEI 9899: 201x - 7.21.6.1-7

Spécifie qu'un spécificateur de conversion d, i, o, u, x, X ou n suivant s'applique à un argument avec un pointeur de type vers short ou unsigned short .

cnicutar
la source
47

Pour scanf, vous devez utiliser %hupuisque vous passez un pointeur vers un fichier unsigned short. Car printf, il est impossible de passer un unsigned shortdû aux promotions par défaut (il sera promu intou unsigned intselon qu'il inta au moins autant de bits de valeur que unsigned shortou non) alors %dou %uc'est bien. Vous êtes cependant libre d'utiliser %husi vous préférez.

R .. GitHub STOP AIDING ICE
la source
7

Depuis la page de manuel Linux:

h Une conversion d'entier suivant correspond à un court int ou un argument court int non signé, ou à un
       La conversion n faible correspond à un pointeur vers un argument int court.

Donc, pour imprimer un entier court non signé, la chaîne de format doit être "%hu".

Un mec programmeur
la source
Je ne pense pas que ce soit comme ça que vous "printf" les entiers courts parce qu'ils sont automatiquement promus en entiers (tout comme les caractères).
Alexey Frunze le
2
@Alex% hu /% hd dans printf fonctionne. C'était% hhu /% hhd qui n'est disponible qu'à partir de C99. % h et% hh impliquent un & 0xFFFF resp. & 0xFF sur l'entier passé.
jørgensen