off_tやsize_tなどのタイプをどのように印刷すればよいですか?


148

off_tおよびのようなタイプを印刷しようとしていますsize_tprintf() 移植可能な正しいプレースホルダーは何ですか?

または、これらの変数を出力するための完全に異なる方法はありますか?


2
@devin:Mac OS X fopenfseek、などを使用しているときにそのタイプoff_tがオフセットに使用されていることがわかったと思います。
GeorgSchölly

回答:


112

次のように、zsize_tとtptrdiff_tに使用できます。

printf("%zu %td", size, ptrdiff);

しかし、私のマンページによると、一部の古いライブラリは別の文字を使用してzおり、その使用を推奨していません。それにもかかわらず、それは(C99標準によって)標準化されています。それらについてintmax_tなどint8_tstdint.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%lluor %lld形式を使用したりできます(もちろん、そうする必要があります)。


2
私のシステムでは、off_tは実際にはlong longで署名されています。
GeorgSchölly、2009

2
manページでは、libc5で使用されていたZ(大文字)の使用は推奨されていないと思います。z(小文字)を妨げるようには見えません。
ドラえもん

12
使用%zdしてすることsize_t、未定義の動作により、符号の有無のミスマッチ(C99 7.19.6.1#9)に。それはそうでなければなりません%zu
Jens

7
では、off_tを印刷する方法は?
JohnyTex 2014

3
私はどのように表示されていない@Jens %zdsize_tその段落から、あるいは任意の他のから未定義の動作を取得します。実際、%z#7の定義では、%dwith size_tおよび対応する符号付きの型が明示的に許可されており、§6.2.5#9では、値が有効な非負の値である限り、対応する符号付きの型が期待される符号なしの型の値を明示的に使用できます。署名されたタイプの。
Chortos-2 2016年

108

印刷するには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これは、小さすぎるために他の一部の実装では失敗します。


3
これははるかに良い答えです。符号なしのsize_tに%zuを使用することを忘れていました。そして、intmax_tへのキャストは、あらゆるプラットフォームのoff_tに対する優れたソリューションです。
Peter Cordes 14

2
POSIXはそれが保証するものではありませんssize_tと同じサイズを持っているsize_tので、本当に移植可能なコードはそれを変換する必要があり、intmax_tかつで印刷%jdだけのようなoff_t
nwellnhof 2017

off_tは最大サイズ、長さ、長さ、および定義に応じて可変である可能性があります... Visual Studioはこれも「警告C4477: '_snprintf_s':フォーマット文字列 '%jd'にはタイプ '__int64'の引数が必要ですが、可変引数1タイプは 'off_t' "です...本当に移植可能な方法はprintf("%lld \ n "、(long long)x);です。
エリックカーチン

5

マイクロソフトにとって、答えは異なります。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が常にlong32ビットになるかどうかに注意してください(64ビットのWindowsでも32ビットをに使用しますlong)。
sourcejedi

3

Cのどのバージョンを使用していますか?

C90では、標準的な方法は、必要に応じて、signedまたはunsigned longにキャストし、それに応じて印刷することです。size_tで%zを見たことがありますが、HarbisonとSteeleはprintf()でそれについて言及していません。いずれにしても、ptrdiff_tなどでは役に立ちません。

C99では、さまざまな_tタイプに独自のprintfマクロが付属しているため"Size is " FOO " bytes." 、詳細はわかりませんが、これはかなり大きな数値形式のインクルードファイルの一部です。


3

inttypes.hのフォーマットマクロを使用する必要があります。

この質問を参照してください: タイプがsize_tの変数のクロスプラットフォームフォーマット文字列?


off_tがptrdiff_tのような符号付きのポインターサイズのint(正確な定義はわかりません)であるとすると、PRIdPTRまたはPRIiPTRを使用します。
マイケルバー

11
off_tタイプは、(これらの日、ほとんどの32ビットシステムで)大きなファイルをサポートしている任意の32ビットシステム上のポインタよりも大きくなっています。
ディートリッヒエップ

1
@DietrichEpp:実際、それよりも悪いです。多くの32ビットシステムにはoff_tとoff64_tの両方があり、機能マクロによっては、off_tは実際にはoff64_tを意味する場合があります。
SamB 2014

1

見ていないman 3 printfのLinux、OS X、とOpenBSDのためのすべてのショーのサポート%zのためにsize_t%tのためにptrdiff_t(C99用)が、それらの言及はいずれもoff_t。野生での提案は、通常アップを提供%uするための変換off_t「正しい十分」としてこれまで私は(両方を伝えることができるようになり、unsigned intそしてoff_t64ビットおよび32ビットのシステム間で同じように異なります)。


1
私のシステム(OS X)には32ビットunsigned intと64 ビットがありますoff_t。したがって、キャストによってデータが失われる可能性があります。
ディートリッヒエップ

-3

受け入れられた回答を覚えるのが難しいため、この投稿を少なくとも2回は見ました(zまたはjフラグを使用することはほとんどなく、プラットフォームに依存しないようです)。

標準では明確の正確なデータ長を言うことはありませんsize_tので、私はあなたが第一の長さをチェックする必要があります示唆、size_tそのうちの一つを選択し、ご使用のプラットフォーム上で:

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

またstdint、一貫性を保つために、生データ型の代わりに型を使用することをお勧めします。


1
C99およびC11の場合、標準では、値の%zu印刷に使用できることが明示的に規定されていsize_tます。/の形式指定子を使用してを出力することは絶対に避けてください。これらの型に互換性があることは保証されていないためです。uint32_tuint64_tsize_t
自閉症の

-4

私が覚えているように、それを行う唯一の移植可能な方法は、結果を "unsigned long int"にキャストしてを使用すること%luです。

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

1
長さ修飾子は変換の前に来る必要があるため、「%lu」にする必要があります。
dwc 2009

1
たとえば、off_tは署名付きlong longです。
GeorgSchölly、2009

@GeorgSchölly- long longC ++標準には存在せず、本質的に移植性がないため、難問に直面しています。
James Curran 2017年

-9

off_tには「%zo」を使用します。(8進数)または10進数の場合は「%zu」。


なぜファイルオフセットを8進数にしたいのですか?
poolie
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.