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 ?
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 ?
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.
Puisque PRId32 n'inclut pas le spécificateur de format %, cela ne devrait-il pas être printf("value: %" PRId32, some_int32_t);
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.
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.
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.
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
.
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) ;
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.
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 ?
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.
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).
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 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.
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.0 votes
Quelle est la manière correcte d'utiliser printf pour imprimer un size_t ?