Comment dois-je imprimer des types comme off_t et size_t?
-
06-09-2019 - |
Question
Je suis en train d'imprimer des types comme off_t
et size_t
. Quel est l'espace réservé correct pour printf()
qui est portable
Ou est-il une manière complètement différente d'imprimer ces variables?
La solution
Vous pouvez utiliser z
pour size_t et t
pour ptrdiff_t comme dans
printf("%zu %td", size, ptrdiff);
Mais ma dit une bibliothèque manpage plus utilisé un caractère différent de celui z
et décourage l'utilisation de celui-ci. Néanmoins, il est standardisé (par la norme C99). Pour les intmax_t
et int8_t
de stdint.h
et ainsi de suite, il y a des macros que vous pouvez utiliser, comme une autre réponse dit:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Ils sont répertoriés dans la page de manuel inttypes.h
.
Personnellement, je voudrais juste jeter les valeurs à unsigned long
ou long
comme une autre réponse recommande. Si vous utilisez C99, vous pouvez (et devriez, bien sûr) jeté à unsigned long long
ou long long
et utiliser les formats de %llu
ou %lld
respectivement.
Autres conseils
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 mise en forme:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Si votre implémentation ne prend pas en charge les codes de mise en forme (par exemple parce que vous êtes sur C89), alors vous avez un peu un problème car il n'y a pas AFAIK types entiers de C89 qui ont des codes de mise en forme et sont garantis être aussi grand que ces types. Donc, vous devez faire quelque chose mise en œuvre spécifique.
Par exemple, si votre compilateur a long long
et votre bibliothèque standard prend en charge %lld
, vous pouvez vous attendre avec confiance qui servira à la place de intmax_t
. Mais si elle ne le fait pas, vous devrez revenir à long
, qui échouerait d'autres implémentations, car il est trop petit.
Pour Microsoft, la réponse est différente. VS2013 est en grande partie conforme à C99, mais "[l] hh, J, Z, et des préfixes de longueur t ne sont pas pris en charge." pour size_t "Qui est, __int32 non signé sur les plates-formes 32 bits, __int64 non signé sur les plates-formes 64 bits" préfixe utilisation I (oeil capital) avec le type spécificateur o, u, x, ou X. Voir les spécifications VS2013 Taille
En ce qui concerne off_t, il est défini tant dans VC \ Include \ sys \ types.h.
Quelle version de C vous utilisez?
En C90, la pratique courante est de jeter à signer ou non signé long, le cas échéant, et l'impression en conséquence. Je l'ai vu z% pour size_t, mais Harbison et Steele ne mentionne pas sous printf (), et en tout cas ce ne serait pas vous aider avec ptrdiff_t ou autre.
En C99, les différents types _t viennent avec leurs propres macros printf, donc quelque chose comme "Size is " FOO " bytes."
je ne sais pas les détails, mais cela fait partie d'un format numérique assez grand fichier inclus.
Vous voulez utiliser les macros de mise en forme de inttypes.h.
Voir cette question: chaîne de format mutualisées pour les variables de type size_t
Regarder man 3 printf
sous Linux, OS X et OpenBSD tout le soutien de spectacle pour %z
pour size_t
et %t
pour ptrdiff_t
(pour C99), mais aucun de ceux off_t
mention. Suggestions dans la nature offrent habituellement la conversion de %u
pour off_t
, qui est « correct assez » pour autant que je peux dire (à la fois unsigned int
et off_t
varient de façon identique entre 64 bits et les systèmes 32 bits).
J'ai vu ce poste au moins deux fois, parce que la réponse acceptée est difficile à remeber pour moi (je l'utilise rarement des drapeaux z
ou j
et ils sont semble pas plateforme indépendante).
Le norme ne dit jamais clairement la longueur exacte des données size_t
, donc je suggère que vous devriez d'abord vérifier la size_t
longueur sur votre plate-forme puis sélectionnez l'une d'entre eux:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Et je suggère d'utiliser les types de stdint
au lieu des types de données brutes pour consistancy.
Si je me souviens, la seule façon portable de le faire, est de jeter le résultat « unsigned long int » et utilisez %lu
.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
utiliser "% zo" pour off_t. (Octal) ou "% zu" pour décimal.