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

J’essaie d’imprimer des types comme off_t et size_t . Quel est l’espace réservé 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 %zd", size, ptrdiff); 

Mais ma page de manuel indique qu’une ancienne bibliothèque utilisait un caractère différent de z et déconseille son utilisation. Néanmoins, il est standardisé (par 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 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 inttypes.h de inttypes.h .

Personnellement, je voudrais simplement placer les valeurs sur unsigned long ou long comme une autre réponse le recommande. Si vous utilisez C99, vous pouvez (et bien entendu) lancer les commandes unsigned long long ou long long et utiliser respectivement les formats %llu ou %lld .

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 mise en forme (par exemple parce que vous êtes sur C89), vous avez un petit problème puisque AFAIK il n’y a pas de types entiers en C89 qui ont des codes de formatage et qui sont garantis comme ces types. Vous devez donc faire quelque chose de spécifique à l’implémentation.

Par exemple, si votre compilateur est long long et que 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 revenir à la version long , ce qui échouerait sur d’autres implémentations car elle est trop petite.

Pour Microsoft, la réponse est différente. VS2013 est en grande partie compatible avec C99 mais “les préfixes de longueur hh, j, z et t ne sont pas supportés.” Pour size_t “c’est-à-dire, __int32 non signé sur les plates-formes 32 bits, les __int64 non signés sur les plates-formes 64 bits” utilisent le préfixe I (majuscule) avec le spécificateur de type o, u, x ou X.

Quant à off_t, elle est définie aussi longtemps dans VC \ include \ sys \ types.h.

Quelle version de C utilisez-vous?

Dans C90, la pratique standard consiste à transtyper en signés long ou non signé, selon le cas, et à 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 chose.

En C99, les différents types _t sont fournis avec 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 d’inclusion de format numérique assez volumineux.

Vous voudrez utiliser les macros de formatage depuis inttypes.h.

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

En regardant man 3 printf sous Linux, OS X et OpenBSD, tous prennent en charge %z pour size_t et %t pour ptrdiff_t (pour C99), mais aucun ne mentionne off_t . Les suggestions dans la nature offrent généralement la conversion %u pour off_t , qui est “suffisamment correcte” pour autant que je off_t (à la fois les unsigned int et les off_t varient de manière identique entre les systèmes 64 bits et 32 ​​bits).

J’ai vu ce post au moins deux fois, car la réponse acceptée est difficile à me rappeler (j’utilise rarement les drapeaux z ou j et ils ne semblent pas indépendants de la plate-forme ).

La norme ne dit jamais clairement la longueur exacte des données de size_t , alors je vous suggère de vérifier d’abord la longueur size_t sur votre plate-forme, puis sélectionnez l’une d’entre elles:

 if sizeof(size_t) == 4 use PRIu32 if sizeof(size_t) == 8 use PRIu64 

Et je suggère d’utiliser des types stdint au lieu de types de données bruts pour la cohérence.

Si je me souviens bien, le seul moyen portable de le faire est de convertir le résultat en “unsigned long int” et d’utiliser %lu .

 printf("sizeof(int) = %lu", (unsigned long) sizeof(int)); 

Veuillez utiliser% lu. Off_t est non signé long.

utilisez “% zo” pour off_t. (octal) ou “% zu” pour les décimales.