Jaki jest specyfikator formatu dla krótkich int bez znaku?

124

Mam następujący program

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

Który po skompilowaniu przy użyciu wygenerował gcc filename.cnastępujące ostrzeżenie (w scanf()linii).

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

Potem przekazał C99 specification - 7.19.6 Formatted input/output functionsi przy użyciu modyfikatorów długość (jakby nie mógł zrozumieć, poprawny format specyfikatora short, longitp) z unsigneddla inttypu danych.

Czy %uwłaściwy specyfikator unsigned short int? Jeśli tak, dlaczego otrzymuję powyższe ostrzeżenie ?!

EDYCJA: Przez większość czasu próbowałem %uhi nadal dawało ostrzeżenie.

Sangeeth Saravanaraj
źródło
2
printf("%u\n", (unsigned int)length); //zawsze działa, ponieważ specyfikacja C99, którą czytasz, gwarantuje to sizeof(short) <= sizeof(int)(ale rzeczywiste odpowiedzi na to pytanie poniżej są oczywiście o wiele ładniejsze)
Philip
1
Nie ma potrzeby obsady; Zadbają o to domyślne promocje.
R .. GitHub STOP POMAGANIE LODOM

Odpowiedzi:

155

Spróbuj użyć "%h"modyfikatora:

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

ISO / IEC 9899: 201x - 7.21.6.1-7

Określa, że ​​następujący po d, i, o, u, x, X lub n specyfikator konwersji ma zastosowanie do argumentu ze wskaźnikiem typu na krótki lub bez znaku .

cnicutar
źródło
47

Dla scanf, trzeba użyć %huponieważ jesteś przechodzącą wskaźnik do unsigned short. Na printf, że to niemożliwe, aby zdać unsigned shortz powodu braku promocji (będzie promowany na intlub unsigned intw zależności od tego, czy intma co najmniej tyle bitów wartość jako unsigned shortlub nie), więc %dczy %ujest w porządku. Możesz jednak używać, %hujeśli wolisz.

R .. GitHub PRZESTAŃ POMÓC LODOWI
źródło
7

Ze strony podręcznika Linux:

h Następująca konwersja liczb całkowitych odpowiada argumentowi short int lub unsigned short int, lub następnemu
       lowing n konwersji odpowiada wskaźnikowi do krótkiego argumentu int.

Aby więc wydrukować krótką liczbę całkowitą bez znaku, łańcuch formatu powinien mieć postać "%hu".

Jakiś koleś programista
źródło
Nie sądzę, że tak właśnie "wypisujesz" krótkie inty, ponieważ są one automatycznie promowane do typu int (tak jak znaki).
Alexey Frunze
2
@Alex% hu /% hd w printf działa. Było to% hhu /% hhd, które jest dostępne tylko od C99. % hi% hh implikuje odp. & 0xFFFF. & 0xFF na przekazanej liczbie całkowitej.
jørgensen