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_t ( PRIxPTR)을 포함하여 모든 유형에 사용 가능한 매크로 의 전체 목록 이 있습니다 . 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

17
PRId64내부적으로로 변환되는 매크로입니다 "lld". 따라서 글을 쓰는 것만 큼printf("%lld\n", t); 설명을 참조하십시오 : qnx.com/developers/docs/6.5.0/…
Gaurav

24
@Gaurav, 일부 플랫폼에서는 사실이지만 모든 것은 아닙니다. 예를 들어 내 amd64 Linux 시스템에서 PRId64는로 정의됩니다 ld. 이식성은 매크로의 이유입니다.
Ethan 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

감사합니다, @ariscris. 매크로는 C ++에만 필요합니다. 링크 된 코드의 정의는#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)내 리눅스 시스템 (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

4
당신은 이식 사용할 수있는 %jd인쇄 int64_t값을 경우 명시 적으로 변환 intmax_t에 전달하기 전에 printf: printf("a=%jd\n", (intmax_t)a). 이것은 <inttypes.h>매크로 의 (IMHO) 추악함을 피 합니다. 물론이 구현에서 지원하는 것으로 가정 %jd, int64_t그리고는 intmax_t, 모두 C99에 의해 추가되었다.
Keith Thompson

2
@KeithThompson 'Ugliness'는 너무 친한 친구를 훨씬 멀리두고 있습니다. 절대적으로 끔찍합니다. 엄청나게. 구역질이 나네요 부끄러운 일입니다. 또는 적어도 그들은 이것을 부끄러워해야합니다. 나는이 매크로를 본 적이 없지만이 답변과 의견-포함 된 제안을 수행하십시오.
Pryftan

나는하지 않는 @Pryftan 확실히 당신이 그들을 아주 추악한 발견 - 나는 그들이 언어 변경없이 덜 추한 방식으로 정의 할 수있는 방법을 모두 확인에 아니에요.
Keith Thompson

@KeithThompson 글쎄, 나는 최소한 'quite'라는 단어에 스트레스를 줘서 고맙다. 실제로는 중요하지 않습니다. 왜 매크로가 있어야하는지 모르겠습니다. 당신이 말할 수 있듯이 ... 등. 그러나 나는 또한 키워드 수의 증가도 손을 out다는 것을 알았습니다.
Pryftan

12

uclibc조차도 항상 사용할 수있는 것은 아니며 임베디드 코드에서 나오는 코드

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

당신은 쓰레기를 인쇄하거나 전혀 작동하지 않습니다-나는 항상 작은 도우미를 사용하여 올바르게 uint64_t 16 진수를 덤프 할 수 있습니다.

#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

리눅스에서는

%lld

18
%lld의 형식이며 반드시와 같을 필요 long long int없습니다int64_t . <stdint.h>에 대한 올바른 형식의 매크로가 있습니다 int64_t. ouah의 답변을 참조하십시오 .
Keith Thompson

@KeithThompson 그러나 long long64 비트 이상 이므로 printf("%lld", (long long)x);아마도 -0x8000000000000000을 제외하고 작동해야 long long합니다.이 유형은 2의 보수를 사용하지 않는 경우 에는 표현할 수 없습니다 .
Pascal Cuoq

@PascalCuoq : 예, 캐스트와 함께 작동해야합니다 (그리고 언급 한 예외는 두 개의 보수를 지원하지만 사용하지 않는 시스템에만 적용되는 경우는 거의 없습니다 long long).
Keith Thompson

-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.