off_t
およびのようなタイプを印刷しようとしていますsize_t
。printf()
移植可能な正しいプレースホルダーは何ですか?
または、これらの変数を出力するための完全に異なる方法はありますか?
off_t
およびのようなタイプを印刷しようとしていますsize_t
。printf()
移植可能な正しいプレースホルダーは何ですか?
または、これらの変数を出力するための完全に異なる方法はありますか?
回答:
次のように、z
size_tとt
ptrdiff_tに使用できます。
printf("%zu %td", size, ptrdiff);
しかし、私のマンページによると、一部の古いライブラリは別の文字を使用してz
おり、その使用を推奨していません。それにもかかわらず、それは(C99標準によって)標準化されています。それらについてintmax_t
などint8_t
、stdint.h
別の答えが言ったように、使用できるマクロがあります:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
それらはのマンページにリストされていinttypes.h
ます。
個人的に、私はちょうどに値をキャストするだろうunsigned long
か、long
別の答えのように推奨しています。C99を使用している場合は、or 形式にキャストしunsigned long long
たりlong long
、%llu
or %lld
形式を使用したりできます(もちろん、そうする必要があります)。
%zd
してすることsize_t
で、未定義の動作により、符号の有無のミスマッチ(C99 7.19.6.1#9)に。それはそうでなければなりません%zu
。
%zd
とsize_t
その段落から、あるいは任意の他のから未定義の動作を取得します。実際、%z
#7の定義では、%d
with size_t
および対応する符号付きの型が明示的に許可されており、§6.2.5#9では、値が有効な非負の値である限り、対応する符号付きの型が期待される符号なしの型の値を明示的に使用できます。署名されたタイプの。
印刷するにはoff_t
:
printf("%jd\n", (intmax_t)x);
印刷するにはsize_t
:
printf("%zu\n", x);
印刷するにはssize_t
:
printf("%zd\n", x);
C99標準の7.19.6.1/7、またはフォーマットコードのより便利なPOSIXドキュメントを参照してください。
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
実装がそれらのフォーマットコードをサポートしていない場合(たとえば、C89を使用しているため)、AFAIKにはフォーマットコードがあり、同じ大きさであることが保証されている整数型がC89にないため、少し問題があります。これらのタイプとして。したがって、実装固有の何かを行う必要があります。
たとえば、コンパイラがlong long
あり、標準ライブラリがサポートしている%lld
場合、がの代わりに機能することを確信して期待できますintmax_t
。しかし、そうでない場合は、にフォールバックする必要があります。long
これは、小さすぎるために他の一部の実装では失敗します。
ssize_t
と同じサイズを持っているsize_t
ので、本当に移植可能なコードはそれを変換する必要があり、intmax_t
かつで印刷%jd
だけのようなoff_t
。
マイクロソフトにとって、答えは異なります。VS2013は主にC99に準拠していますが、「hh、j、z、tの長さのプレフィックスはサポートされていません。」size_tの場合、つまり、32ビットプラットフォームでは符号なし__int32、64ビットプラットフォームでは符号なし__int64の場合は、プレフィックスI(大文字のアイ)と型指定子o、u、x、またはX を使用します。VS2013サイズ仕様を参照してください。
off_tについては、VC \ include \ sys \ types.hでlongとして定義されています。
off_t
が常にlong
32ビットになるかどうかに注意してください(64ビットのWindowsでも32ビットをに使用しますlong
)。
inttypes.hのフォーマットマクロを使用する必要があります。
この質問を参照してください: タイプがsize_tの変数のクロスプラットフォームフォーマット文字列?
off_t
タイプは、(これらの日、ほとんどの32ビットシステムで)大きなファイルをサポートしている任意の32ビットシステム上のポインタよりも大きくなっています。
見ていないman 3 printf
のLinux、OS X、とOpenBSDのためのすべてのショーのサポート%z
のためにsize_t
と%t
のためにptrdiff_t
(C99用)が、それらの言及はいずれもoff_t
。野生での提案は、通常アップを提供%u
するための変換off_t
「正しい十分」としてこれまで私は(両方を伝えることができるようになり、unsigned int
そしてoff_t
64ビットおよび32ビットのシステム間で同じように異なります)。
unsigned int
と64 ビットがありますoff_t
。したがって、キャストによってデータが失われる可能性があります。
受け入れられた回答を覚えるのが難しいため、この投稿を少なくとも2回は見ました(z
またはj
フラグを使用することはほとんどなく、プラットフォームに依存しないようです)。
標準では明確の正確なデータ長を言うことはありませんsize_t
ので、私はあなたが第一の長さをチェックする必要があります示唆、size_t
そのうちの一つを選択し、ご使用のプラットフォーム上で:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
またstdint
、一貫性を保つために、生データ型の代わりに型を使用することをお勧めします。
%zu
印刷に使用できることが明示的に規定されていsize_t
ます。/の形式指定子を使用してを出力することは絶対に避けてください。これらの型に互換性があることは保証されていないためです。uint32_t
uint64_t
size_t
私が覚えているように、それを行う唯一の移植可能な方法は、結果を "unsigned long int"にキャストしてを使用すること%lu
です。
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long long
C ++標準には存在せず、本質的に移植性がないため、難問に直面しています。
fopen
でfseek
、などを使用しているときにそのタイプoff_t
がオフセットに使用されていることがわかったと思います。