Wie soll ich Typen wie off_t und size_t drucken?

Lesezeit: 6 Minuten

Benutzeravatar von Georg Schölly
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?

  • @devin: Ich glaube, ich habe diesen Typ bei der Verwendung gefunden fopen, fseekusw. 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

Johannes Schaub - Benutzerbild der litb
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

Benutzeravatar von Steve Jessop
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 %lldSie können getrost davon ausgehen, dass dies anstelle von dienen wird intmax_t. Aber wenn nicht, müssen Sie darauf zurückgreifen longwas 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_talso 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.

Benutzeravatar von Michael Burr
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

Benutzeravatar von dwc
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_twas “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

Benutzeravatar von 12431234123412341234123
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.

1424610cookie-checkWie soll ich Typen wie off_t und size_t drucken?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy