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?
c
portability
format-specifiers
Georg Schölly
quelle
quelle
fopen
,fseek
etc. auf Mac OS Xoff_t
ist für den Offset verwendet.Antworten:
Sie können
z
für size_t undt
für ptrdiff_t wie in verwendenAber 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 dieseintmax_t
undint8_t
vonstdint.h
und so weiter gibt es Makros, die Sie verwenden können, wie eine andere Antwort sagte: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 dieselong
empfehlen. Wenn Sie C99 verwenden, dann können Sie (und sollte natürlich) abgegeben zuunsigned long long
oderlong long
und verwenden Sie die%llu
oder%lld
Formate sind.quelle
%zd
mit asize_t
ist aufgrund der Nichtübereinstimmung der Vorzeichen undefiniert (C99 7.19.6.1 # 9). Es muss sein%zu
.%zd
mit einemsize_t
undefinierten Verhalten aus diesem Absatz oder aus einem anderen. Tatsächlich%z
erlaubt die Definition von in # 7 explizit%d
mitsize_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
:So drucken Sie
size_t
:So drucken Sie
ssize_t
: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 wirdintmax_t
. Wenn dies nicht der Fall ist, müssen Sielong
auf etwas zurückgreifen , was bei einigen anderen Implementierungen fehlschlagen würde, weil es zu klein ist.quelle
ssize_t
es die gleiche Größe hat wiesize_t
, daher sollte wirklich portabler Code es in genau so konvertierenintmax_t
und mit%jd
genau so druckenoff_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.
quelle
off_t
immerlong
der Fall ist, wird es 32-Bit (selbst 64-Bit-Windows verwendet 32-Bit fürlong
).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.quelle
Sie möchten die Formatierungsmakros von inttypes.h verwenden.
Siehe diese Frage: Plattformübergreifende Formatzeichenfolge für Variablen vom Typ size_t?
quelle
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ürsize_t
und%t
fürptrdiff_t
(für C99) angezeigt, aber keine davon erwähntoff_t
. Vorschläge in freier Wildbahn bieten normalerweise die%u
Konvertierung füroff_t
, was meines Erachtens "richtig genug" ist (beideunsigned int
undoff_t
variieren identisch zwischen 64-Bit- und 32-Bit-Systemen).quelle
unsigned int
und 64-Bitoff_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
oderj
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ängesize_t
auf Ihrer Plattform zu überprüfen und dann eine davon auszuwählen:Und ich schlage vor,
stdint
aus Gründen der Konsistenz Typen anstelle von Rohdatentypen zu verwenden.quelle
%zu
zum Drucken vonsize_t
Werten verwendet werden kann. Man sollte definitiv nicht auf die Verwendung einesuint32_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
.quelle
long long
es im C ++ - Standard nicht existiert und daher von Natur aus nicht portierbar ist.benutze "% zo" für off_t. (oktal) oder "% zu" für dezimal.
quelle