J'essaie d'imprimer des types tels que off_t
Et size_t
. Quel est le paramètre fictif correct pour printf()
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 que certaines bibliothèques plus anciennes utilisaient un caractère différent de z
et déconseillent son utilisation. Néanmoins, il est normalisé (selon la norme C99). Pour ceux intmax_t
et int8_t
de stdint.h
et ainsi de suite, il existe des macros que vous pouvez utiliser, comme le disait 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 voudrais juste jeter les valeurs sur unsigned long
ou long
comme le recommande une autre réponse. Si vous utilisez C99, vous pouvez (et devez bien sûr) transtyper en unsigned long long
ou long long
et utilisez le %llu
ou %lld
formats respectivement.
Imprimer off_t
:
printf("%jd\n", (intmax_t)x);
Imprimer size_t
:
printf("%zu\n", x);
Imprimer ssize_t
:
printf("%zd\n", x);
Voir 7.19.6.1/7 de la norme C99, ou la documentation POSIX plus pratique sur les codes de formatage:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Si votre implémentation ne prend pas en charge ces codes de formatage (par exemple parce que vous êtes sur C89), vous rencontrez un problème car AFAIK ne contient pas de types entiers dans C89 qui possèdent des codes de formatage et sont garantis aussi gros. comme 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 prend en charge %lld
, vous pouvez vous attendre à ce que cela serve à la place de intmax_t
. Mais si ce n'est pas le cas, vous devrez vous replier sur long
, ce qui échouerait sur d'autres implémentations car elles sont trop petites.
Pour Microsoft, la réponse est différente. VS2013 est largement conforme à C99 mais "les préfixes de longueur hh, j, z et t ne sont pas pris en charge." Pour size_t ", c'est-à-dire non signé __int32 sur les plates-formes 32 bits, non signé __int64 sur les plates-formes 64 bits", utilisez le préfixe I (majuscule) avec le spécificateur de type o, u, x ou X. Voir Spécification de taille VS201
Quant à off_t, il est défini aussi longtemps dans VC\include\sys\types.h.
Vous voudrez utiliser les macros de formatage de inttypes.h.
Voir cette question: Chaîne de formats inter-plateformes pour les variables de type size_t?
Quelle version de C utilisez-vous?
En C90, la pratique standard est de transtyper au format signé ou non signé long, selon le cas, et d’imprimer en conséquence. J'ai vu% z pour size_t, mais Harbison et Steele ne le mentionnent pas dans printf (), et dans tous les cas cela ne vous aiderait pas avec ptrdiff_t ou autre.
En C99, les différents types de _t sont livrés avec leurs propres macros printf. Quelque chose comme "Size is " FOO " bytes."
Je ne connais pas les détails, mais cela fait partie d’un fichier d’inclusion au format assez volumineux.
Regarder man 3 printf
sur Linux, OS X et OpenBSD montrent tous la prise en charge de %z
pour size_t
et %t
pour ptrdiff_t
(pour C99), mais aucun d’eux ne mentionne off_t
. Les suggestions dans la nature offrent généralement le %u
conversion pour off_t
, qui est "assez correct" pour autant que je sache (les deux unsigned int
et off_t
varient de manière identique entre les systèmes 64 bits et 32 bits).