web-dev-qa-db-fra.com

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

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?

141
Georg Schölly

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.

104

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.

102
Steve Jessop

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.

5
NoBrassRing

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?

3
Michael Burr

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.

3
David Thornley

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).

1
dwc