web-dev-qa-db-ja.com

uint32_tおよびsize_tのprintf形式指定子

私は次のものを持っています

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

コンパイル時に次の警告が表示されます。

format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’

スプリントを使用してこれを実行すると、次のようになりました:

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

アドバイスをありがとう

90
ant2009

size_tが実際にunsigned long(32ビット)である場合、unsigned int(おそらく64ビット)と同じであると期待しているように聞こえます。両方の場合で%zuを使用してみてください。

しかし、私は完全に確実ではありません。

22
Cogwheel

試してみる

#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);

zsize_tと同じ長さの整数を表し、PRIu32マクロ、 C99ヘッダーで定義inttypes.h は、符号なし32を表します-ビット整数。

125
kennytm

必要なのは、書式指定子と型が一致することだけで、いつでもキャストしてそれを実現できます。 longは少なくとも32ビットなので、%lu(unsigned long)kは常に正しいです。

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_tは扱いにくいため、C99で%zuが追加されました。それを使用できない場合は、kのように扱います(longはC89で最大の型であり、size_tが大きくなる可能性は非常に低いです)。

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

渡そうとしている型に合った書式指定子を取得できない場合、printfは配列からメモリを読みすぎたり、読みすぎたりするのと同じことをします。明示的なキャストを使用して型を一致させる限り、移植性があります。

23
u0b34a0f6ae

PRI *マクロを使用したくない場合、ANY整数型を印刷する別の方法は、intmax_tまたはuintmax_tにキャストし、それぞれ"%jd"または%juを使用することです。これは、PRI_ *マクロが定義されていないPOSIX(または他のOS)タイプ、たとえばoff_tで特に役立ちます。

16
R..