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


101

私は以下を持っています

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

アドバイスありがとうございます。


2
C89はuint32_tfrom <stdint.h>またはをサポートしていません<inttypes.h>。これらのタイプを使用する場合は、C89にアップグレードする必要があります。拡張機能として、GCCではそれらの使用を許可している可能性がありますが、C89にはそのようなサポートはありませんでした。
ジョナサンレフラー、

10
の公式C99形式修飾子size_tは、「z」"%zu"です。
ジョナサンレフラー、


@ケニーの答えはに最適だと思いますuint32_tが、それは欠けていsize_tます。@ u0b34a0f6aeの回答には両方が含まれています。
jww

Jonathan Lefflerによる最初のコメントでのC89の2番目の言及はC99である必要があります
bph '19

回答:


28

実際には(32ビット)であるときに(おそらく64ビット)size_tと同じであると期待しているように聞こえます。どちらの場合にも使用してみてください。unsigned longunsigned int%zu

私は完全に確かではありませんが。


1
コンパイル時に警告はありません。しかし、スプリントを実行すると、私は、次を得る:1)のprintf(%u)はunsigned int型はのuint32_tを取得見込ん:私は2)のprintf(%u)はunsigned int型はsize_t型を取得見込ん:K
ant2009

スプリントのように聞こえるのは、それだけで、今はすごい。それはおそらくソースコードの型の名前から外れていて、それらが同等であることを認識していません。@KennyTMの答えでどうなるのだろう...それは確かにより移植性があるはずです。
Cogwheel 2010

3
スプリントは実際に正しいことをしています。理由だけでint32_tあることを起こるintあなたのコンパイラ/プラットフォーム上でそれはないかもしれないという意味ではありませんlong別に。も同じですsize_t。簡単で自然なチェックは、コンパイラーが行うようにtypedefを尊重するだけなので、実際には邪魔にならず、この移植性のバグを検出するための作業が増えています。
R .. GitHub STOP HELPING ICE

4
-1、ポータブルではありません。必要なことは、フォーマット指定子とタイプが一致することだけであり、いつでもキャストしてそれをtrueにすることができます。longは少なくとも32ビットなので、%lu一緒にする(unsigned long)kと常に正しいです。C99で追加されsize_tたのはそのため%zuです。それを使用できない場合は、klongC89で最大の型で、これsize_tより大きくなることはほとんどありません)のように扱います。
u0b34a0f6ae

139

試す

#include <inttypes.h>
...

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

z同じ長さの整数を表しsize_t、そしてPRIu32マクロ、C99ヘッダに定義されているがinttypes.h、符号なし32ビット整数を表します。


3
@robUK:へえ。スプリントのバグを報告することをお勧めします。
kennytm 2010

8
これが正解です。私の個人的な推薦は単にキャストすることですが、例えばprintf( "%lu", (unsigned long )i )。それ以外の場合は、型の変更により、コード全体に警告が山積みになってしまいます。
Dummy00001 2010

1
これが正解です。スプリントのバグの提出についてKennyTMに同意します。ちなみに、「%zu」はsize_tの適切な形式です。size_tを印刷するためにPRI *マクロは必要ありません。
R .. GitHub ICE HELPING ICEの停止

1
私が正しく覚えているとすれば、%zuはC99であり、質問では彼は 'C89'と書きました。
alcor 2013年

8
@alcorはい、彼はC89(明らかに彼が使用しuint32_tているgccコンパイラフラグ)を配置しましたが、実際に使用しているため、C99コードであり、そのようにコンパイルする必要があります。
Colin D Bennett

28

必要なことは、フォーマット指定子とタイプが一致することだけであり、いつでもキャストしてそれをtrueにすることができます。long32ビット以上なので、と%lu一緒に(unsigned long)k常に正しい:

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

size_t%zuC99で追加されたのはそのためです。それを使用できない場合は、klongC89で最大の型で、これsize_tより大きくなることはほとんどありません)のように扱います。

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

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


17

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.