158 votes

Comment dois-je imprimer des types comme off_t et size_t ?

J'essaie d'imprimer des types comme off_t y size_t . Quel est le caractère de remplacement correct pour printf() qui est portable ?

Ou existe-t-il une manière complètement différente d'imprimer ces variables ?

2 votes

@devin : Je crois que j'ai trouvé ce type en utilisant fopen , fseek etc. sur Mac OS X. off_t est utilisé pour le décalage.

122voto

Johannes Schaub - litb Points 256113

Vous pouvez utiliser z pour size_t et t pour ptrdiff_t comme dans

printf("%zu %td", size, ptrdiff);

Mais ma page de manuel indique qu'une ancienne bibliothèque utilisait un caractère différent que z et décourage son utilisation. Néanmoins, il est normalisé (par la norme C99). Pour ceux intmax_t y int8_t de stdint.h et ainsi de suite, il existe des macros que vous pouvez utiliser, comme l'a dit une autre réponse :

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

Ils sont listés dans la page de manuel de inttypes.h .

Personnellement, je me contenterais de convertir les valeurs en unsigned long o long comme le recommande une autre réponse. Si vous utilisez C99, vous pouvez (et devriez, bien sûr) effectuer un cast vers unsigned long long o long long et utiliser le %llu o %lld respectivement.

0 votes

Puisque PRId32 n'inclut pas le spécificateur de format %, cela ne devrait-il pas être printf("value: %" PRId32, some_int32_t);

3 votes

Off_t est en fait un long long signé sur mon système.

0 votes

Oui pour les valeurs signées vous devrez convertir en long ou long long. ce dernier type n'existe pas dans le C++ actuel - mais la prochaine version l'inclura. surtout si vous travaillez avec posix et qu'il inclut certains types comme off_t qui ont de grandes tailles, vous devez faire attention.

121voto

Steve Jessop Points 166970

Pour imprimer off_t :

printf("%jd\n", (intmax_t)x);

Pour imprimer size_t :

printf("%zu\n", x);

Pour imprimer ssize_t :

printf("%zd\n", x);

Voir 7.19.6.1/7 dans la norme C99, ou la documentation POSIX plus pratique des codes de formatage :

http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

Si votre implémentation ne supporte pas ces codes de formatage (par exemple parce que vous êtes sur C89), alors vous avez un petit problème puisque AFAIK il n'y a pas de types entiers dans C89 qui ont des codes de formatage et sont garantis d'être aussi grands que ces types. Vous devez donc faire quelque chose de spécifique à l'implémentation.

Par exemple, si votre compilateur a long long et votre bibliothèque standard supporte %lld vous pouvez vous attendre en toute confiance à ce qu'il serve à la place de intmax_t . Mais si ce n'est pas le cas, vous devrez vous rabattre sur long qui échouerait dans certaines autres implémentations parce qu'il est trop petit.

3 votes

C'est de loin la meilleure réponse, j'aurais oublié d'utiliser %zu pour unsigned size_t. Et le moulage en intmax_t est une excellente solution pour tout ce qui est off_t sur n'importe quelle plateforme.

3 votes

POSIX ne garantit pas que ssize_t a la même taille que size_t donc un code réellement portable devrait le convertir en intmax_t et imprimer avec %jd juste comme off_t .

0 votes

Off_t peut être jusqu'à la taille long long et peut être variable en fonction des définitions... Visual Studio prévient aussi avec ceci "warning C4477 : '_snprintf_s' : format string '%jd' requires an argument of type '__int64', but variadic argument 1 has type 'off_t'"... Une façon vraiment portable est printf("%lld \n ", (long long)x) ;

5voto

NoBrassRing Points 1

Pour Microsoft, la réponse est différente. VS2013 est largement conforme à la norme C99, mais " les préfixes de longueur hh, j, z et t ne sont pas pris en charge. " Pour size_t "c'est-à-dire unsigned __int32 sur les plateformes 32 bits, unsigned __int64 sur les plateformes 64 bits", utilisez le préfixe I (œil majuscule) avec le spécificateur de type o, u, x ou X. Voir les spécifications de taille de VS2013

Quant à off_t, il est défini comme long dans VC \include\sys\types.h.

0 votes

Note si off_t est toujours long ce qui en ferait un 32 bits (même Windows 64 bits utilise le 32 bits pour l'accès aux données). long ).

3voto

Michael Burr Points 181287

Vous devez utiliser les macros de formatage de inttypes.h.

Voir cette question : Chaîne de format multiplateforme pour les variables de type size_t ?

0 votes

En supposant que off_t soit un int signé, de la taille d'un pointeur (je ne connais pas la définition précise) comme ptrdiff_t, vous utiliserez PRIdPTR ou PRIiPTR.

11 votes

El off_t est plus grand qu'un pointeur sur n'importe quel système 32 bits qui supporte les gros fichiers (ce qui est le cas de la plupart des systèmes 32 bits de nos jours).

1 votes

@DietrichEpp : En fait, c'est pire que cela ; de nombreux systèmes 32 bits ont à la fois off_t et off64_t, et selon les macros de fonctionnalités off_t peut en fait signifier off64_t.

3voto

David Thornley Points 39051

Quelle version de C utilisez-vous ?

En C90, la pratique standard est d'effectuer un cast vers un long signé ou non signé, selon le cas, et d'imprimer en conséquence. J'ai vu %z pour size_t, mais Harbison et Steele ne le mentionnent pas sous printf(), et de toute façon cela ne vous aiderait pas avec ptrdiff_t ou autre.

En C99, les différents types _t sont accompagnés de leurs propres macros printf, donc quelque chose comme "Size is " FOO " bytes." Je ne connais pas les détails, mais cela fait partie d'un fichier include de format numérique assez important.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X