Wie soll ich Typen wie off_t und size_t drucken?
-
06-09-2019 - |
Frage
Ich versuche, Typen wie off_t
und size_t
zu drucken. Was ist der richtige Platzhalter für printf()
das ist tragbar
Oder gibt es eine ganz andere Art und Weise, diese Variablen zu drucken?
Lösung
Sie können z
für size_t und t
für ptrdiff_t wie in
printf("%zu %td", size, ptrdiff);
Aber meine manpage sagt einige ältere Bibliothek einen anderen Charakter als z
verwendet und schreckt Gebrauch davon. Trotzdem ist es standardisiert (von dem C99-Standard). Für die intmax_t
und int8_t
von stdint.h
und so weiter, gibt es Makros, die Sie verwenden können, wie eine andere Antwort, sagte:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Sie sind in der Manual-Page von inttypes.h
aufgeführt.
Persönlich würde ich werfe nur die Werte wie die andere Antwort auf unsigned long
oder long
empfiehlt. Wenn Sie C99 verwenden, dann können Sie (und sollte natürlich) gegossen oder unsigned long long
long long
und jeweils die %llu
oder %lld
Formate verwenden.
Andere Tipps
off_t
drucken:
printf("%jd\n", (intmax_t)x);
size_t
drucken:
printf("%zu\n", x);
ssize_t
drucken:
printf("%zd\n", x);
Siehe 7.19.6.1/7 in dem C99-Standard oder die bequemere POSIX-Dokumentation von Formatierungscodes:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Wenn Sie Ihre Implementierung nicht diese Formatierungscodes nicht unterstützt (zum Beispiel, weil Sie auf C89 sind), dann haben Sie ein bisschen ein Problem, da AFAIK es nicht Integer-Typen in C89 sind die Formatierungscodes haben und sind garantiert so groß wie diese Art sein. Sie müssen also etwas Implementierung spezifischen tun.
Zum Beispiel, wenn Ihr Compiler hat long long
und Ihre Standardbibliothek unterstützt %lld
, können Sie getrost erwarten, dass anstelle von intmax_t
dienen. Aber wenn dies nicht der Fall, werden Sie zurück zu long
fallen müssen, die auf einigen anderen Implementierungen scheitern würde, weil es zu klein ist.
Für Microsoft ist die Antwort anders aus. VS2013 ist weitgehend C99-konform, sondern "[d] ie hh, j, z und t Länge Präfixe nicht unterstützt werden." für size_t "Das heißt, ohne Vorzeichen __int32 auf 32-Bit-Plattformen, ohne Vorzeichen __int64 auf 64-Bit-Plattformen" Verwendung Präfix I (Kapital Auge) mit Typspezifizierer o, u, x oder X. sehen Sie VS2013 Größe Spezifikation
Wie bei off_t, es so lange in VC \ definiert ist, umfasst sys \ types.h \.
Welche Version von C verwenden Sie?
In C90, die gängige Praxis ist, mit oder ohne Vorzeichen lange, soweit angemessen, und Druck entsprechend zu werfen. Ich habe für size_t gesehen% z, aber Harbison und Steele erwähnen Sie es nicht unter printf (), und in jedem Fall, dass Sie nicht helfen würde, mit ptrdiff_t oder was auch immer.
In C99, die verschiedenen _t Typen kommen mit ihrer eigenen printf Makros, so etwas wie "Size is " FOO " bytes."
ich Details weiß es nicht, aber das ist Teil eines ziemlich großen numerischen Formats Include-Datei.
Sie wollen die Formatierungs Makros aus inttypes.h verwenden.
Sehen Sie diese Frage: Plattformübergreifend Format-String für Variablen Typ size_t?
Mit Blick auf man 3 printf
unter Linux, OS X und OpenBSD alle zeigen Unterstützung für %z
für size_t
und %t
für ptrdiff_t
(für C99), aber keiner der Erwähnung off_t
. Vorschläge in der freien Natur bieten in der Regel die %u
Umwandlung für off_t
auf, die „richtig genug“, soweit ich sagen kann, ist, (beide unsigned int
und off_t
variieren identisch zwischen 64-Bit- und 32-Bit-Systemen).
Ich sah diesen Beitrag mindestens zweimal, weil die akzeptierte Antwort für mich schwer zu remeber ist (I z
oder j
Flaggen selten verwenden und sie sind, scheint nicht plattformunabhängig ).
Die Standard sagt nie eindeutig die genaue Datenlänge von size_t
, so schlage ich vor, Sie zum ersten Mal auf die Länge size_t
überprüfen sollten, Ihre Plattform dann wählen sie eine von ihnen:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Und ich schlage vor stdint
Typen anstelle von Rohdaten Typen für consistancy verwendet wird.
Wie ich mich erinnere, ist die einzige tragbare Art und Weise, es zu tun, ist das Ergebnis „unsigned long int“ zu werfen und %lu
verwenden.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
verwenden "% zo" für off_t. (Oktal) oder "% zu" für dezimal.