Cでint64_t型を出力する方法


298

C99標準には、int64_tのようなバイトサイズの整数型があります。次のコードを使用しています。

#include <stdio.h>
#include <stdint.h>
int64_t my_int = 999999999999999999;
printf("This is my_int: %I64d\n", my_int);

そして、私はこのコンパイラ警告を受け取ります:

warning: format ‘%I64d expects type int’, but argument 2 has type int64_t

私が試した:

printf("This is my_int: %lld\n", my_int); // long long decimal

しかし、同じ警告が表示されます。私はこのコンパイラを使用しています:

~/dev/c$ cc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5664~89/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5664)

警告なしにmy_int変数を出力するにはどの形式を使用すればよいですか?


回答:


420

以下のためのint64_tタイプ:

#include <inttypes.h>
int64_t t;
printf("%" PRId64 "\n", t);

以下のためのuint64_tタイプ:

#include <inttypes.h>
uint64_t t;
printf("%" PRIu64 "\n", t);

PRIx6416進数での印刷にも使用できます。

cppreference.comには、intptr_tPRIxPTR)を含むすべてのタイプで使用可能なマクロの完全なリストがあります。のようなscanfには個別のマクロがありますSCNd64


PRIu16の一般的な定義は"hu"であるため、コンパイル時に暗黙の文字列定数連結が発生します。

コードを完全に移植可能にするには、などを使用PRId32してを印刷int32_t"%d"たり、同様の方法でを印刷したりする必要がありますint


18
書式設定マクロ定数の完全なリスト:en.cppreference.com/w/cpp/types/integer
Massood Khaari

12
また、LinuxでC ++を使用している場合は、インクルードする#define __STDC_FORMAT_MACROS前に確認してくださいinttypes.h
csl 2014年

17
PRId64内部的にに変換されるマクロ"lld"です。だから、それは書くように良いようですprintf("%lld\n", t);:説明を参照してくださいqnx.com/developers/docs/6.5.0/...
のGaurav

24
@Gaurav、それは一部のプラットフォームでは当てはまりますが、すべてでは当てはまりません。たとえば、私のamd64 Linuxマシンでは、PRId64はとして定義されていldます。移植性がマクロの理由です。
イーサンT

10
私はいくつかの追加の努力でそれをさらに不愉快にすることができたと思います
Pavel P

65

C99の方法は

#include <inttypes.h>
int64_t my_int = 999999999999999999;
printf("%" PRId64 "\n", my_int);

またはキャストできます!

printf("%ld", (long)my_int);
printf("%lld", (long long)my_int); /* C89 didn't define `long long` */
printf("%f", (double)my_int);

C89実装(特にVisual Studio)で行き詰まっている場合は、おそらくオープンソース<inttypes.h>(および<stdint.h>)を使用できます。http//code.google.com/p/msinttypes/


code.google.comリンクからmsinttypesを使用する場合、__ STDC_FORMAT_MACROSを定義する必要があります。stackoverflow.com/questions/8132399/how-to-printf-uint64-tをご覧ください。
アリスクリス

頭を上げてくれてありがとう、@ ariscris。ただし、マクロはC ++にのみ必要なようです。リンクされているコードの定義は、aの内部にあります#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
pmg

19

C99と%j長調節剤はまた、型の値印刷する機能のprintfのファミリーで使用することができるint64_tとしuint64_t

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    int64_t  a = 1LL << 63;
    uint64_t b = 1ULL << 63;

    printf("a=%jd (0x%jx)\n", a, a);
    printf("b=%ju (0x%jx)\n", b, b);

    return 0;
}

このコードをコンパイルしてgcc -Wall -pedantic -std=c99警告は生成されず、プログラムは予期される出力を出力します。

a=-9223372036854775808 (0x8000000000000000)
b=9223372036854775808 (0x8000000000000000)

これは、に応じているprintf(3)私のLinuxシステム上で(manページには、具体的と言いjへの変換を示すために使用されたintmax_tかをuintmax_t、私のstdint.hで、両方int64_tintmax_t、同様のためにまったく同じ方法でtypedefされuint64_t)。これが他のシステムに完全に移植可能かどうかはわかりません。


12
場合%jdprnts intmax_t、正しい呼び出しは次のようになりますprintf("a=%jd (0x%jx)", (intmax_t) a, (intmax_t) a)int64_tintmax_tが同じ型であるという保証はなく、そうでない場合の動作は未定義です。
user4815162342 2013

4
あなたは、移植性を使用することができます%jd印刷するint64_t値を場合は、明示的にそれらを変換intmax_tに渡す前にprintfprintf("a=%jd\n", (intmax_t)a)。これは、<inttypes.h>マクロの(IMHO)醜さを回避します。もちろん、これはあなたの実装がサポートすることを前提とし%jdint64_t、とはintmax_t、すべてがC99で追加されました。
キーストンプソン

2
@KeithThompson 'Ugliness'は、親切に対応しすぎています。それは絶対に恐ろしいです。それは恐ろしいことです。吐き気がする。恥ずかしいのはそれが何であるかです。あるいは、少なくとも彼らは恥ずかしいはずです。私はこれらのマクロを見たことがありませんが、この答えとコメント-あなたが含まれている-が示唆することを実行します。
Pryftan

@Pryftan それらはあなたほど醜くはありません-そして、言語を変更せずにそれらをそれほど醜くない方法でどのように定義することができるのか全くわかりません。
キース・トンプソン、

@KeithThompsonさて、少なくとも「かなり」という言葉に力を入れていただき、ありがとうございます。まあ実際にはそれは問題ではありません。なぜマクロが存在しなければならないのかわかりません。あなたが携帯できると言っているように...等。しかし、それから私はまた、キーワードの数の増加が手に負えなくなっていることもわかります。
Pryftan

12

uclibcでさえ常に利用できるわけではない組み込みの世界から来て、

uint64_t myval = 0xdeadfacedeadbeef; printf("%llx", myval);

がらくたを印刷している、またはまったく機能していない-私は常に小さなヘルパーを使用しています。これにより、uint64_t hexを適切にダンプできます。

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

char* ullx(uint64_t val)
{
    static char buf[34] = { [0 ... 33] = 0 };
    char* out = &buf[33];
    uint64_t hval = val;
    unsigned int hbase = 16;

    do {
        *out = "0123456789abcdef"[hval % hbase];
        --out;
        hval /= hbase;
    } while(hval);

    *out-- = 'x', *out = '0';

    return out;
}

組み込みアプリケーションでこの問題に直面している場合は、これが探しているものです。この解決策は私にとってうまくいきました。Thnx @ataraxic
Logan859

8

Windows環境では、

%I64d

Linuxでは、

%lld

18
%lldはの形式でlong long int、必ずしもと同じではありませんint64_t<stdint.h>の正しい形式のマクロがありますint64_touahの回答を参照してください。
キーストンプソン

@KeithThompsonただし、long long少なくとも64ビットなので、printf("%lld", (long long)x);おそらく-0x8000000000000000を除いて機能するはずです。これはlong long、その型が2の補数を使用していない場合、として表現できませんでした。
Pascal Cuoq 2013

@PascalCuoq:はい、キャストで動作するはずです(そして、あなたが言及した例外は2の補数をサポートするがには使用しないシステムにのみ適用されることはほとんどありませんlong long)。
キーストンプソン

-3

//VC6.0(386以上)

    __int64 my_qw_var = 0x1234567890abcdef;

    __int32 v_dw_h;
    __int32 v_dw_l;

    __asm
        {
            mov eax,[dword ptr my_qw_var + 4]   //dwh
            mov [dword ptr v_dw_h],eax

            mov eax,[dword ptr my_qw_var]   //dwl
            mov [dword ptr v_dw_l],eax

        }
        //Oops 0.8 format
    printf("val = 0x%0.8x%0.8x\n", (__int32)v_dw_h, (__int32)v_dw_l);

よろしく。

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