Ich versuche Typen wie off_t
und zu drucken size_t
. Was ist der richtige Platzhalter dafür printf()
ist tragbar ?
Oder gibt es eine ganz andere Möglichkeit, diese Variablen zu drucken?
Ich versuche Typen wie off_t
und zu drucken size_t
. Was ist der richtige Platzhalter dafür printf()
ist tragbar ?
Oder gibt es eine ganz andere Möglichkeit, diese Variablen zu drucken?
Antworten:
Sie können z
für size_t und t
für ptrdiff_t wie in verwenden
printf("%zu %td", size, ptrdiff);
Aber meine Manpage sagt, dass einige ältere Bibliotheken einen anderen Charakter verwendet haben z
und davon abraten, ihn zu verwenden. Trotzdem ist es standardisiert (nach dem C99-Standard). Für diese 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 Manpage von aufgeführt inttypes.h
.
Persönlich würde ich die Werte einfach auf eine andere Antwort übertragen unsigned long
oder diese long
empfehlen. Wenn Sie C99 verwenden, dann können Sie (und sollte natürlich) abgegeben zu unsigned long long
oder long long
und verwenden Sie die %llu
oder %lld
Formate sind.
%zd
mit a size_t
ist aufgrund der Nichtübereinstimmung der Vorzeichen undefiniert (C99 7.19.6.1 # 9). Es muss sein %zu
.
%zd
mit einem size_t
undefinierten Verhalten aus diesem Absatz oder aus einem anderen. Tatsächlich %z
erlaubt die Definition von in # 7 explizit %d
mit size_t
und dem entsprechenden vorzeichenbehafteten Typ, und §6.2.5 # 9 erlaubt explizit die Verwendung von Werten vorzeichenloser Typen, bei denen der entsprechende vorzeichenbehaftete Typ erwartet wird, solange der Wert ein gültiger nichtnegativer Wert ist vom signierten Typ.
So drucken Sie off_t
:
printf("%jd\n", (intmax_t)x);
So drucken Sie size_t
:
printf("%zu\n", x);
So drucken Sie ssize_t
:
printf("%zd\n", x);
Siehe 7.19.6.1/7 im C99-Standard oder die bequemere POSIX-Dokumentation der Formatierungscodes:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Wenn Ihre Implementierung diese Formatierungscodes nicht unterstützt (z. B. weil Sie sich auf C89 befinden), haben Sie ein kleines Problem, da AFAIK in C89 keine Ganzzahltypen mit Formatierungscodes enthält, die garantiert so groß sind wie diese Typen. Sie müssen also etwas Implementierungsspezifisches tun.
Wenn Ihr Compiler beispielsweise über long long
eine Standardbibliothek verfügt und diese unterstützt %lld
, können Sie davon ausgehen, dass diese anstelle von verwendet wird intmax_t
. Wenn dies nicht der Fall ist, müssen Sie long
auf etwas zurückgreifen , was bei einigen anderen Implementierungen fehlschlagen würde, weil es zu klein ist.
ssize_t
es die gleiche Größe hat wie size_t
, daher sollte wirklich portabler Code es in genau so konvertieren intmax_t
und mit %jd
genau so drucken off_t
.
Für Microsoft ist die Antwort anders. VS2013 ist weitgehend C99-kompatibel, aber "[h] die Präfixe für die Länge hh, j, z und t werden nicht unterstützt." Verwenden Sie für size_t "dh __int32 ohne Vorzeichen auf 32-Bit-Plattformen, __int64 ohne Vorzeichen auf 64-Bit-Plattformen" das Präfix I (Großbuchstabe) mit dem Typbezeichner o, u, x oder X. Siehe VS2013-Größenangabe
Off_t wird in VC \ include \ sys \ types.h als lang definiert.
off_t
immer long
der Fall ist, wird es 32-Bit (selbst 64-Bit-Windows verwendet 32-Bit für long
).
Welche Version von C verwenden Sie?
In C90 besteht die Standardpraxis darin, je nach Bedarf auf signiertes oder nicht signiertes Long zu gießen und entsprechend zu drucken. Ich habe% z für size_t gesehen, aber Harbison und Steele erwähnen es nicht unter printf (), und das würde dir auf jeden Fall bei ptrdiff_t oder was auch immer nicht helfen.
In C99 werden die verschiedenen _t-Typen mit eigenen printf-Makros geliefert. "Size is " FOO " bytes."
Ich kenne also keine Details, aber das ist Teil einer ziemlich großen Include-Datei im numerischen Format.
Sie möchten die Formatierungsmakros von inttypes.h verwenden.
Siehe diese Frage: Plattformübergreifende Formatzeichenfolge für Variablen vom Typ size_t?
off_t
Typ ist größer als ein Zeiger auf einem 32-Bit-System, das große Dateien unterstützt (dies sind heutzutage die meisten 32-Bit-Systeme).
Unter man 3 printf
Linux, OS X und OpenBSD wird die Unterstützung %z
für size_t
und %t
für ptrdiff_t
(für C99) angezeigt, aber keine davon erwähnt off_t
. Vorschläge in freier Wildbahn bieten normalerweise die %u
Konvertierung für off_t
, was meines Erachtens "richtig genug" ist (beide unsigned int
und off_t
variieren identisch zwischen 64-Bit- und 32-Bit-Systemen).
unsigned int
und 64-Bit off_t
. Die Besetzung würde also dazu führen, dass Daten verloren gehen.
Ich habe diesen Beitrag mindestens zweimal gesehen, da die akzeptierte Antwort für mich schwer zu merken ist (ich verwende selten z
oder j
Flaggen und sie scheinen nicht plattformunabhängig zu sein ).
Der Standard gibt niemals klar die genaue Datenlänge von an size_t
. Ich empfehle daher, zuerst die Länge size_t
auf Ihrer Plattform zu überprüfen und dann eine davon auszuwählen:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Und ich schlage vor, stdint
aus Gründen der Konsistenz Typen anstelle von Rohdatentypen zu verwenden.
%zu
zum Drucken von size_t
Werten verwendet werden kann. Man sollte definitiv nicht auf die Verwendung eines uint32_t
/ uint64_t
Format- size_t
Bezeichners zurückgreifen, um einen zu drucken , da es keine Garantie dafür gibt, dass diese Typen kompatibel sind.
Soweit ich mich erinnere, besteht die einzige tragbare Möglichkeit darin, das Ergebnis in "unsigned long int" umzuwandeln und zu verwenden %lu
.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long long
es im C ++ - Standard nicht existiert und daher von Natur aus nicht portierbar ist.
fopen
,fseek
etc. auf Mac OS Xoff_t
ist für den Offset verwendet.