プラットフォームに依存しないsize_tcのフォーマット指定子?


86

size_tCで型の変数を出力したいのですが、size_tアーキテクチャーごとに異なる変数型にエイリアスされているようです。たとえば、あるマシン(64ビット)では、次のコードは警告をスローしません。

size_t size = 1;
printf("the size is %ld", size);

しかし、他のマシン(32ビット)では、上記のコードは次の警告メッセージを生成します。

警告:フォーマット '%ld'はタイプ 'long int *'を予期していますが、引数3のタイプは 'size_t *'です。

これはポインタサイズの違いによるものと思われるため、64ビットマシンでsize_tlong int"%ld")にエイリアスされますが、32ビットマシンでsize_tは別のタイプにエイリアスされます。

専用のフォーマット指定子はありsize_tますか?


警告メッセージがコードと一致しません。警告にはポインタが記載されていますが、コードにはポインタがありません。&どこかを削除しましたか?
イェンス

ポインタ?いいえ、ポインタに関する警告は表示されません。実際、そのコードを実行するマシンによっては、警告がまったく表示されない場合があります。次のテストコードを試してください。#include <stdio.h> int main(){size_t size = 1; printf( "サイズは%ld"、size); 0を返します。}
Ethan Heilman 2012


1
@EthanHeilman彼はあなたの警告が言っていることに言及だwarning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *'それはおそらく時にすべきであると言ってすることwarning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'scanf()これらの警告が表示されたときに、代わりに使用していましたか?
RastaJedi 2016

回答:


123

はい:z長さ修飾子を使用します:

size_t size = sizeof(char);
printf("the size is %zu\n", size);  // decimal size_t ("u" for unsigned)
printf("the size is %zx\n", size);  // hex size_t

使用可能な他の長さ修飾子は、hh(for char)、h(for short)、l(for long)、ll(for long long)、j(for intmax_t)、t(for ptrdiff_t)、およびL(for long double)です。C99標準の§7.19.6.1(7)を参照してください。


zdとzuの違いは何ですか?zdは10進数であることがわかりますが、署名されている場合、署名されているzdはどのように影響しますか。
イーサンハイルマン2010年

1
これは、asize_tssize_t;の違いです。後者はめったに使用されません。
アダムローゼンフィールド2010年

26
そうです、この場合、%zu引数は符号なしなので、を使用する必要があります。
caf 2010年

使用可能な他のオプションについては、printfのマニュアルページで説明されています。linux.die.net
INS

9
@detly:いいえ、z長さ修飾子はC89 / C90の一部ではありません。C89準拠のコードを目指している場合、できる最善の方法は、キャストしてunsigned longl代わりに長さ修飾子を使用することprintf("the size is %lu\n", (unsigned long)size);です。C89と、size_tそれよりも大きいシステムの両方をサポートするのlongは難しいため、多数のプリプロセッサマクロを使用する必要があります。
Adam Rosenfield 2014年

45

はいあります。それは%zu(ANSI C99で指定されているように)です。

size_t size = 1;
printf("the size is %zu", size);

size_tは符号なしであるため%ld、二重に間違っていることに注意してください。長さ修飾子とフォーマット変換指定子が間違っています。ご参考までに、%zdfor ssize_t(署名済み)です。


1

MSDNによると、Visual Studioは、32ビットおよび64ビットプラットフォームで移植可能なコードの「I」プレフィックスをサポートしているとのことです。

size_t size = 10;
printf("size is %Iu", size);

6
これはMS固有であり、標準に準拠していないため、プラットフォームに依存しません
phuclv 2016年

@phuclv確かに。そして、それが本当に言うなら-答えが示唆するように-'ポータブル'それは私がMSについて知っていたよりもさらに悪いです。それは私を驚かせるというわけではありません...誰かが何かに答えようと努力したので私は反対票を投じる人ではありませんが、それでもこの答えは間違っています。ああ、私はここの「ポータブル」のアイデアを理解していると思います。32ビットと64ビットの両方で機能すると言っているに違いありません。しかしもちろんそうなるでしょう。
プリフタン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.