1. ホーム
  2. c

[解決済み] ino_tのようなサイズ不明の型はどうすれば印刷できますか?

2022-02-10 07:21:42

質問内容

で印刷したい場面はよくあります。 printf 実装で定義されたサイズの整数型(例えば ino_t または time_t ). 今現在、私はこのようなパターンを使っています。

#include <inttypes.h>

ino_t ino; /* variable of unknown size */
printf("%" PRIuMAX, (uintmax_t)ino);

この方法は今のところうまくいっていますが、いくつかの欠点があります。

  • 印刷しようとする型が符号付きか符号なしかを知っておかなければならない。
  • 型キャストを使用しなければならないので、コードが大きくなる可能性がある。

もっと良い方法はないでしょうか?

どのように解決するのか?

#include <inttypes.h>
ino_t ino; /* variable of unknown size */
/* ... */
printf("%" PRIuMAX, (uintmax_t)ino);

それは確かにうまくいくだろうが(いくつかの但し書きがある。

printf("%ju", (uintmax_t)ino);

j 長さ修飾子

以下のように指定します。 d , i , o , u , x または X 変換指定子が適用されるのは intmax_t または uintmax_t 引数、または以下の n 変換 へのポインタに適用されます。 intmax_t の引数になります。

もあります。 zt のモディファイアは size_tptrdiff_t (と、それぞれ対応する符号付き型/符号なし型)。

また、個人的には <inttypes.h> は醜く、覚えにくいので、私は "%ju" または "%jd" .

ご指摘の通り、型( ino_t この場合、符号付きか符号なし)。たまたまそれがわからなかったとしても、解明することは可能です。

#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>

#define IS_SIGNED(type) ((type)-1 < (type)0)
#define DECIMAL_FORMAT(type) (IS_SIGNED(type) ? "%jd" : "%ju")
#define CONVERT_TO_MAX(type, value) \
    (IS_SIGNED(type) ? (intmax_t)(value) : (uintmax_t)(value))
#define PRINT_VALUE(type, value) \
    (printf(DECIMAL_FORMAT(type), CONVERT_TO_MAX(type, (value))))

int main(void) {
    ino_t ino = 42;
    PRINT_VALUE(ino_t, ino);
    putchar('\n');
}

が、これはやりすぎかもしれません。もし、型が64ビットより狭いことが確かなら、その値を intmax_t で、その値は保存されます。あるいは uintmax_t を印刷し、すべての値について明確に定義された結果を得ることができます。 -1 として 18446744073709551615 (2 64 -1)は、少しわかりにくいかもしれません。

これらはすべて、C言語の実装が以下のものをサポートしている場合にのみ機能します。 <stdint.h> と、その j の長さ修飾子です。 printf -- つまり、C99をサポートしているかどうかです。すべてのコンパイラがそうであるとは限りません ( せき マイクロソフト ). C90の場合、最も広い整数型は longunsigned long に変換して使用することができます。 "%ld" および "%lu" . 理論的には、C99準拠のテストは __STDC_VERSION__ 定義済みマクロ -- ただし、C99以前のコンパイラの中には、まだ longunsigned long を拡張子として使用します。