Próbuję drukować typy takie jak off_t
i size_t
. Jaki jest prawidłowy symbol zastępczy dla printf()
tego, że jest przenośny ?
A może jest zupełnie inny sposób drukowania tych zmiennych?
c
portability
format-specifiers
Georg Schölly
źródło
źródło
fopen
,fseek
itp na Mac OS X.off_t
służy do przesunięcia.Odpowiedzi:
Możesz użyć
z
dla size_t it
dla ptrdiff_t jak wAle moja strona podręcznika mówi, że jakaś starsza biblioteka używała innego znaku niż
z
i zniechęca do jego używania. Niemniej jednak jest znormalizowany (według standardu C99). Dla tychintmax_t
iint8_t
odstdint.h
i tak dalej, są makra można użyć, jak inna odpowiedź powiedział:Są one wymienione na stronie podręcznika
inttypes.h
.Osobiście chciałbym po prostu przypisać wartości
unsigned long
lublong
polubić inne zalecenia. Jeśli korzystasz z C99, następnie można (a nawet powinien, oczywiście) oddanych dounsigned long long
lublong long
i użyj%llu
lub%lld
formatów odpowiednio.źródło
%zd
z asize_t
jest niezdefiniowanym zachowaniem z powodu niezgodności podpisów (C99 7.19.6.1 # 9). To musi być%zu
.%zd
pomocą asize_t
uzyskuje się niezdefiniowane zachowanie z tego akapitu lub innego. W rzeczywistości, definicja%z
w 7 wyraźnie zezwala%d
sięsize_t
i podpisał odpowiedni typ i §6.2.5 # 9 wyraźnie pozwala na stosowanie wartości niepodpisanych typów gdzie spodziewane jest odpowiedni typ podpisana, dopóki wartość jest prawidłową wartością dodatnią podpisanego typu.Aby wydrukować
off_t
:Aby wydrukować
size_t
:Aby wydrukować
ssize_t
:Zobacz 7.19.6.1/7 w standardzie C99 lub wygodniejszą dokumentację POSIX dotyczącą kodów formatowania:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Jeśli twoja implementacja nie obsługuje tych kodów formatujących (na przykład ponieważ jesteś na C89), masz mały problem, ponieważ AFAIK nie ma typów całkowitych w C89, które mają kody formatujące i gwarantują, że są tak duże jak te typy. Musisz więc zrobić coś specyficznego dla implementacji.
Na przykład, jeśli Twój kompilator ma
long long
i obsługuje standardową bibliotekę%lld
, możesz śmiało oczekiwać, że będzie to służyć zamiastintmax_t
. Ale jeśli tak się nie stanie, będziesz musiał wrócić dolong
, co w przypadku niektórych innych implementacji nie powiedzie się, ponieważ jest za małe.źródło
ssize_t
ma taki sam rozmiar jaksize_t
, więc prawdziwie przenośny kod powinien go konwertowaćintmax_t
i drukować z%jd
takim samymoff_t
.W przypadku firmy Microsoft odpowiedź jest inna. VS2013 jest w dużej mierze zgodny z C99, ale „[t] he hh, j, z i t prefiksy długości nie są obsługiwane”. Dla size_t "to znaczy unsigned __int32 na platformach 32-bitowych, unsigned __int64 na platformach 64-bitowych" użyj przedrostka I (wielkie oko) ze specyfikatorem typu o, u, x lub X. Zobacz specyfikację rozmiaru VS2013
Jeśli chodzi o off_t, jest zdefiniowany jako długi w VC \ include \ sys \ types.h.
źródło
off_t
zawsze jestlong
to 32-bitowe (nawet 64-bitowy system Windows używa 32-bitowegolong
).Której wersji C używasz?
W C90 standardową praktyką jest rzutowanie odpowiednio do długości ze znakiem lub bez znaku i odpowiednie drukowanie. Widziałem% z dla size_t, ale Harbison i Steele nie wspominają o tym w printf (), aw każdym razie to nie pomoże ci z ptrdiff_t lub czymkolwiek.
W C99 różne typy _t mają własne makra printf, więc coś w rodzaju
"Size is " FOO " bytes."
nie znam szczegółów, ale jest to część dość dużego pliku dołączanego formatu liczbowego.źródło
Będziesz chciał użyć makr formatujących z inttypes.h.
Zobacz to pytanie: Ciąg formatu międzyplatformowego dla zmiennych typu size_t?
źródło
off_t
Typ jest większy niż wskaźnik w dowolnym systemie 32-bitowym, który obsługuje duże pliki (co jest większość 32-bitowe systemy te dni).Patrząc
man 3 printf
na Linuksa, OS X i OpenBSD, wszystkie pokazują wsparcie%z
dlasize_t
i%t
dlaptrdiff_t
(dla C99), ale żadne z nich nie wspominaoff_t
. Sugestie w środowisku naturalnym zazwyczaj oferują%u
konwersjęoff_t
, która jest „wystarczająco poprawna”, o ile wiem (obaunsigned int
ioff_t
różnią się identycznie między systemami 64-bitowymi i 32-bitowymi).źródło
unsigned int
i 64-bitowyoff_t
. Więc obsada spowodowałaby utratę danych.Widziałem ten post co najmniej dwa razy, ponieważ zaakceptowaną odpowiedź trudno mi zapamiętać (rzadko używam
z
lubj
flag i wydaje się, że nie są niezależne od platformy ).Norma nie mówi wyraźnie dokładna długość danych
size_t
, więc proponuję najpierw należy sprawdzić długośćsize_t
od platformy, a następnie wybrać jedną z nich:I sugeruję używanie
stdint
typów zamiast surowych typów danych w celu zachowania spójności.źródło
%zu
których można użyć do wydrukowaniasize_t
wartości. Trzeba na pewno nie uciekać się do korzystania zuint32_t
/uint64_t
formatu specyfikatora aby wydrukowaćsize_t
, ponieważ nie ma gwarancji, że te typy są kompatybilne.Jak sobie przypominam, jedynym przenośnym sposobem na zrobienie tego jest rzutowanie wyniku na „unsigned long int” i użycie
%lu
.źródło
long long
nie istnieje w standardzie C ++, a zatem jest z natury nieprzenośny.użyj „% zo” dla off_t. (ósemkowo) lub „% zu” dla liczby dziesiętnej.
źródło