2012-08-25 10 views
33

Próbuję wydrukować wartość uint16_t i uint32_t, ale nie daje pożądanego o/p.Jak wydrukować wartości zmiennych uint32_t i uint16_t?

#include<stdio.h> 
#include <netinet/in.h> 

int main() 
{ 
    uint32_t a=12,a1; 
    uint16_t b=1,b1; 
    a1=htonl(a); 
    printf("%d---------%d",a1); 
    b1=htons(b); 
    printf("\n%d-----%d",b,b1); 
    return 0; 
} 

użyłem również

printf("%"PRIu32, a); 

który pokazując błąd.

Jak wydrukować te wartości, a co będzie żądany O/P

+3

O wiele lepiej byłoby pokazać nam (dokładny!) Komunikat o błędzie, niż po prostu powiedzieć, że "pokazuje błąd". I zamiast "nie dawać pożądanego o/p", pokaż nam rzeczywiste wyniki (i przeliteruj słowo "wyjście", zamiast pisać "o/p"). –

Odpowiedz

53

trzeba podać inttypes.h jeśli chcesz te wszystkie ładne nowe specyfikatory format intN_t typów i ich braci i że jest poprawny (tzn. przenośny) sposób, aby to zrobić, pod warunkiem, że twój kompilator jest zgodny z C99. Nie powinieneś używać standardowych, takich jak %d lub %u, jeśli rozmiary różnią się od Twoich.

Zawiera stdint.h i rozszerza go o kilka innych rzeczy, takich jak makra, które mogą być używane dla rodziny połączeń printf/scanf. Jest to opisane w sekcji 7.8 normy ISO C99.

Na przykład, następujący program:

#include <stdio.h> 
#include <inttypes.h> 
int main (void) { 
    uint32_t a=1234; 
    uint16_t b=5678; 
    printf("%" PRIu32 "\n",a); 
    printf("%" PRIu16 "\n",b); 
    return 0; 
} 

wyjścia:

1234 
5678 
12

Makra zdefiniowane w <inttypes.h> są najbardziej poprawny sposób aby wydrukować wartości typów uint32_t, uint16_t, i tak dalej - - ale nie są one jedyną drogą.

Osobiście uważam te makra za trudne do zapamiętania i niewygodne w użyciu. (Biorąc pod uwagę składnię ciągu formatu printf, prawdopodobnie jest to nieuniknione, nie twierdzę, że mogłem wymyślić lepszy system.)

Alternatywą jest rzutowanie wartości na predefiniowany typ i użycie formatu dla ten typ.

Rodzaje int i unsigned int gwarantuje języka na co najmniej długość 16 bitów, a więc w stanie utrzymać każdą przekonwertowany wartość typu int16_t lub uint16_t, odpowiednio. Podobnie, long i unsigned long mają szerokość co najmniej 32 bity, a long long i unsigned long long mają szerokość co najmniej 64 bitów.

Na przykład, mogę napisać swój program tak (z kilkoma dodatkowymi szczypie):

#include <stdio.h> 
#include <stdint.h> 
#include <netinet/in.h> 

int main(void) 
{ 
    uint32_t a=12, a1; 
    uint16_t b=1, b1; 
    a1 = htonl(a); 
    printf("%lu---------%lu\n", (unsigned long)a, (unsigned long)a1); 
    b1 = htons(b); 
    printf("%u-----%u\n", (unsigned)b, (unsigned)b1); 
    return 0; 
} 

Zaletą tego podejścia jest to, że może pracować nawet z pre-C99 wdrożeń, które nie obsługują <inttypes.h>. Taka implementacja najprawdopodobniej nie miałaby również wartości <stdint.h>, ale technika ta jest użyteczna w przypadku innych typów liczb całkowitych.

+1

Jest tu jeden bardzo mały przypadek krawędziowy, jeśli podpisany int nie jest dopełnieniem dwójki. W takim przypadku nie będzie prawidłowo przechowywać najbardziej ujemnej wartości uzupełnienia dwójki. BARDZO drobne, przyznaję, ale coś, na co trzeba uważać, jeśli zależy ci na maksymalnej przenośności. – paxdiablo

+1

@paxdiablo: Typy 'intN_t' muszą być uzupełnieniem dwójkowym bez dopełnień. Jeśli 'int' nie jest dopełnieniem dwójki, to typy' intN_t' prawdopodobnie nie zostaną zdefiniowane *, chyba że * implementacja obsługuje również różne typy dopełnień typu dwa-dopełniacz. Dobra rada, ale myślę, że jest to nawet bardziej drobny przypadek niż sugerujesz. –

+1

Bez wątpienia. Podejrzewam, że trudno byłoby znaleźć maszynę na planecie, która nosiła nowe typy integralne, ale wciąż miała "dopełnienie" lub znak/magnitudę typu "int" :-) – paxdiablo

-2

W moim przypadku używam tylko %u, aby wyprowadzić wartość z typem uint32_t. To działa.

np.

uint32_t i = 31 - __builtin_clz(mask); 

    D("read i= %u ", __FUNCTION__, i); 
+2

Spowoduje to niezdefiniowane zachowanie w systemach, w których 'sizeof (unsigned int)! = sizeof (uint32_t) '. – user694733

+0

Dzięki, bro. Odkryłem też, że możemy użyć '% 08x', aby go przedstawić. Zostanie wyświetlony jako binarny. –

+1

Użycie '% 08x' ma ten sam problem co'% u'. Ponadto wyświetli wartość jako liczbę szesnastkową; nie ma binarnego specyfikatora w standardowym C printf. – user694733

Powiązane problemy