Standard C99 ma typy liczb całkowitych o rozmiarze bajtów jak int64_t. Korzystam z następującego kodu:
#include <stdio.h>
#include <stdint.h>
int64_t my_int = 999999999999999999;
printf("This is my_int: %I64d\n", my_int);
i dostaję to ostrzeżenie kompilatora:
warning: format ‘%I64d’ expects type ‘int’, but argument 2 has type ‘int64_t’
Próbowałem z:
printf("This is my_int: %lld\n", my_int); // long long decimal
Ale dostaję to samo ostrzeżenie. Korzystam z tego kompilatora:
~/dev/c$ cc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5664~89/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5664)
Jakiego formatu należy użyć, aby wydrukować zmienną my_int bez ostrzeżenia?
Odpowiedzi:
Dla
int64_t
typu:dla
uint64_t
typu:możesz także użyć
PRIx64
do drukowania w systemie szesnastkowym.cppreference.com ma pełną listę dostępnych makr dla wszystkich typów, w tym
intptr_t
(PRIxPTR
). Istnieją osobne makra dla scanf, takie jakSCNd64
.Typowa definicja PRIu16 byłaby
"hu"
, więc domniemana ciągła konkatenacja ciągów zachodzi w czasie kompilacji.Na Twój kod będzie w pełni przenośne, należy użyć
PRId32
i tak dalej do drukowaniaint32_t
i"%d"
czy podobna do drukowaniaint
.źródło
#define __STDC_FORMAT_MACROS
przed włączenieminttypes.h
.PRId64
to makro, które wewnętrznie się tłumaczy"lld"
. Jest więc tak dobry jak pisanieprintf("%lld\n", t);
Zobacz opis: qnx.com/developers/docs/6.5.0/…ld
. Przenośność jest przyczyną tego makra.Sposób C99 jest
Lub możesz rzucić!
Jeśli utkniesz z implementacją C89 (zwłaszcza Visual Studio), być może możesz użyć open source
<inttypes.h>
(i<stdint.h>
): http://code.google.com/p/msinttypes/źródło
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
W C99
%j
modyfikator długości może być również używany z rodziną funkcji printf do drukowania wartości typuint64_t
iuint64_t
:Kompilowanie tego kodu bez
gcc -Wall -pedantic -std=c99
żadnych ostrzeżeń, a program wypisuje oczekiwane dane wyjściowe:Jest to według
printf(3)
w moim systemie Linux (strona człowiek specjalnie mówi, żej
jest używany do wskazywania konwersji naintmax_t
lubuintmax_t
, w moim stdint.h, zarównoint64_t
iintmax_t
są typedef'd dokładnie w ten sam sposób i podobnie douint64_t
). Nie jestem pewien, czy jest to idealnie przenośne dla innych systemów.źródło
%jd
prnts anintmax_t
, poprawne wywołanie byłobyprintf("a=%jd (0x%jx)", (intmax_t) a, (intmax_t) a)
. Nie ma gwarancji, że sąint64_t
iintmax_t
są tego samego typu, a jeśli nie są, zachowanie jest niezdefiniowane.%jd
do drukowaniaint64_t
wartości jeśli jawnie przekonwertować jeintmax_t
przed przekazaniem ich doprintf
:printf("a=%jd\n", (intmax_t)a)
. Pozwala to uniknąć brzydoty<inttypes.h>
makr (IMHO) . Oczywiście to zakłada się, że wspiera wdrożenie%jd
,int64_t
orazintmax_t
, z których wszystkie zostały dodane przez C99.Pochodzi z wbudowanego świata, w którym nawet uclibc nie zawsze jest dostępny i podobny do kodu
uint64_t myval = 0xdeadfacedeadbeef; printf("%llx", myval);
drukuje ci bzdury lub wcale nie działa - zawsze używam małego pomocnika, który pozwala mi poprawnie zrzucić szesnastkę uint64_t:
źródło
W środowisku Windows użyj
w systemie Linux użyj
źródło
%lld
to formatlong long int
, który nie koniecznie taka sama, jakint64_t
.<stdint.h>
ma makro odpowiedniego formatuint64_t
; zobacz odpowiedź ouah .long long
jest co najmniej 64-bitowy,printf("%lld", (long long)x);
powinien działać, z wyjątkiem być może -0x8000000000000000, co nie może być reprezentowane jako,long long
jeśli ten typ nie używa uzupełnienia dwóch.long long
).//VC6.0 (386 i więcej)
Pozdrowienia.
źródło