Ich versuche, Typen wie zu drucken off_t
und size_t
. Wofür ist der richtige Platzhalter? printf()
das ist tragbar?
Oder gibt es eine ganz andere Möglichkeit, diese Variablen zu drucken?
Georg Scholly
Ich versuche, Typen wie zu drucken off_t
und size_t
. Wofür ist der richtige Platzhalter? printf()
das ist tragbar?
Oder gibt es eine ganz andere Möglichkeit, diese Variablen zu drucken?
Johannes Schaub – litb
Sie können verwenden z
für size_t und t
für ptrdiff_t wie in
printf("%zu %td", size, ptrdiff);
Aber meine Manpage sagt, dass einige ältere Bibliotheken ein anderes Zeichen als verwendet haben z
und rät von deren Verwendung ab. Trotzdem ist es standardisiert (durch den C99-Standard). Für diejenigen intmax_t
und int8_t
von stdint.h
und so weiter, es gibt 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 aufgelistet inttypes.h
.
Ich persönlich würde die Werte einfach auf casten unsigned long
oder long
wie eine andere Antwort empfiehlt. Wenn Sie C99 verwenden, dann können (und sollten Sie natürlich) darauf umwandeln unsigned long long
oder long long
und benutze die %llu
oder %lld
Formate bzw.
off_t ist auf meinem System tatsächlich ein signiertes Long Long.
– Georg Scholly
27. Februar 2009 um 22:56 Uhr
Ich denke, die Manpage rät von der Verwendung von Z (Großbuchstaben) ab, das von libc5 verwendet wurde. Es scheint z (Kleinbuchstaben) nicht zu entmutigen.
– Draemon
26. Mai 2010 um 22:17 Uhr
Verwenden %zd
mit einer size_t
ist undefiniertes Verhalten aufgrund der Vorzeichenabweichung (C99 7.19.6.1#9). Es muss sein %zu
.
– Jens
2. März 2013 um 8:31 Uhr
Nun, wie druckt man dann off_t?
– JohnyTex
25. Juli 2014 um 16:01 Uhr
@Jens Ich verstehe nicht wie %zd
mit einer size_t
erhält undefiniertes Verhalten von diesem oder einem anderen Absatz. Tatsächlich ist die Definition von %z
in #7 ausdrücklich erlaubt %d
mit size_t
und dem entsprechenden vorzeichenbehafteten Typ, und §6.2.5#9 erlaubt explizit die Verwendung von Werten von vorzeichenlosen Typen, wo der entsprechende vorzeichenbehaftete Typ erwartet wird, solange der Wert ein gültiger nicht negativer Wert des vorzeichenbehafteten Typs ist.
– Chortos-2
29. Oktober 2016 um 18:54 Uhr
Steve Jessop
Zu drucken off_t
:
printf("%jd\n", (intmax_t)x);
Zu drucken size_t
:
printf("%zu\n", x);
Zu drucken ssize_t
:
printf("%zd\n", x);
Siehe 7.19.6.1/7 im C99-Standard oder die bequemere POSIX-Dokumentation von 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 es AFAIK in C89 keine Integer-Typen gibt, die Formatierungscodes haben und garantiert so groß sind wie diese Typen. Sie müssen also etwas Implementierungsspezifisches tun.
Zum Beispiel, wenn Ihr Compiler hat long long
und Ihre Standardbibliothek unterstützt %lld
Sie können getrost davon ausgehen, dass dies anstelle von dienen wird intmax_t
. Aber wenn nicht, müssen Sie darauf zurückgreifen long
was bei einigen anderen Implementierungen fehlschlagen würde, weil es zu klein ist.
Dies ist bei weitem die bessere Antwort, ich hätte vergessen, %zu für unsigned size_t zu verwenden. Und das Casting in intmax_t ist eine großartige Lösung für alles, was off_t auf jeder Plattform ist.
– Peter Cordes
28. Dezember 2014 um 1:13 Uhr
POSIX garantiert das nicht ssize_t
hat die gleiche Größe wie size_t
also sollte wirklich portabler Code ihn in konvertieren intmax_t
und mit drucken %jd
so wie off_t
.
– nwellnhof
30. September 2017 um 15:11 Uhr
off_t kann bis zu Größe lang lang sein und kann je nach Definition variabel sein … Visual Studio warnt damit auch “warning C4477: ‘_snprintf_s’ : format string ‘%jd’ require an argument of type ‘__int64’, but variadic argument 1 has type ‘off_t'”… Ein wirklich portabler Weg ist printf(“%lld\n”, (long long)x);
– Ericcurtin
13. Juni 2018 um 16:59 Uhr
Für Microsoft ist die Antwort anders. VS2013 ist weitgehend C99-kompatibel, aber ”
Was off_t betrifft, so ist es in VC\include\sys\types.h als lang definiert.
Beachten Sie ggf off_t
ist immer long
das würde es zu 32-Bit machen (selbst 64-Bit-Windows verwendet 32-Bit für long
).
– Quellejedi
22. August 2015 um 13:48 Uhr
Welche C-Version verwendest du?
In C90 besteht die Standardpraxis darin, je nach Bedarf in vorzeichenbehaftete oder vorzeichenlose Länge umzuwandeln 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 Ihnen sowieso nicht mit ptrdiff_t oder was auch immer helfen.
In C99 haben die verschiedenen _t-Typen ihre eigenen printf-Makros, also so etwas wie "Size is " FOO " bytes."
Ich kenne keine Details, aber das ist Teil einer ziemlich großen Include-Datei im numerischen Format.
Michael Burr
Sie sollten die Formatierungsmakros aus inttypes.h verwenden.
Siehe diese Frage: Plattformübergreifende Formatzeichenfolge für Variablen vom Typ size_t?
Angenommen, off_t ist ein signiertes, zeigergroßes int (ich weiß nicht, was die genaue Definition ist), wie ptrdiff_t, dann würden Sie PRIdPTR oder PRIiPTR verwenden.
– Michael Burr
27. April 2009 um 20:31 Uhr
Das off_t
type ist größer als ein Zeiger auf jedem 32-Bit-System, das große Dateien unterstützt (was heutzutage die meisten 32-Bit-Systeme sind).
– Dietrich Ep
24. Mai 2010 um 23:22 Uhr
@DietrichEpp: Eigentlich ist es noch schlimmer; Viele 32-Bit-Systeme haben sowohl off_t als auch off64_t, und abhängig von den Funktionsmakros kann off_t tatsächlich off64_t bedeuten.
– SamB
31. Juli 2014 um 2:05 Uhr
dwc
Anschauen man 3 printf
unter Linux, OS X und OpenBSD zeigen alle Unterstützung für %z
zum size_t
und %t
zum ptrdiff_t
(für C99), aber keiner von denen erwähnt off_t
. Vorschläge in freier Wildbahn bieten normalerweise das an %u
Konvertierung für off_t
was “richtig genug” ist, soweit ich das beurteilen kann (beide unsigned int
und off_t
zwischen 64-Bit- und 32-Bit-Systemen identisch variieren).
Angenommen, off_t ist ein signiertes, zeigergroßes int (ich weiß nicht, was die genaue Definition ist), wie ptrdiff_t, dann würden Sie PRIdPTR oder PRIiPTR verwenden.
– Michael Burr
27. April 2009 um 20:31 Uhr
Das off_t
type ist größer als ein Zeiger auf jedem 32-Bit-System, das große Dateien unterstützt (was heutzutage die meisten 32-Bit-Systeme sind).
– Dietrich Ep
24. Mai 2010 um 23:22 Uhr
@DietrichEpp: Eigentlich ist es noch schlimmer; Viele 32-Bit-Systeme haben sowohl off_t als auch off64_t, und abhängig von den Funktionsmakros kann off_t tatsächlich off64_t bedeuten.
– SamB
31. Juli 2014 um 2:05 Uhr
12431234123412341234123
Wenn Sie C11 oder C18 verwenden, können Sie verwenden _Generic
.
#include <stdio.h>
#include <sys/types.h>
#define TYPE_FORMAT(variable) _Generic \
( \
(variable) \
, unsigned char : "%hhu" \
, unsigned short : "%hu" \
, unsigned int : "%u" \
, unsigned long : "%lu" \
, unsigned long long : "%llu" \
, signed char : "%hhi" \
, signed short : "%hi" \
, signed int : "%i" \
, signed long : "%li" \
, signed long long : "%lli" \
)
int main(void)
{
off_t a=3321;
printf(TYPE_FORMAT(a), a);
}
Es gibt jedoch einen großen Nachteil: Sie können auf diese Weise keine Zeichenfolgen kombinieren. Bedeutet dies:
printf("Foo: " TYPE_FORMAT(a), a);
wird nicht funktionieren, was es für viele Situationen unbrauchbar macht. Ja, Sie könnten die Zeichenfolge während der Laufzeit kombinieren, aber das ist ärgerlich.
@devin: Ich glaube, ich habe diesen Typ bei der Verwendung gefunden
fopen
,fseek
usw. unter Mac OS X.off_t
wird für den Offset verwendet.– Georg Scholly
23. März 2010 um 17:40 Uhr
Was ist der richtige Weg, um printf zu verwenden, um ein size_t zu drucken?
– phuklv
27. Juni 2018 um 7:11 Uhr