Hoe een int64_t-type in C af te drukken

C99-standaard heeft integer-typen met bytes-grootte zoals int64_t. Ik gebruik de volgende code:

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

en ik krijg deze compilerwaarschuwing:

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

Ik heb geprobeerd met:

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

Maar ik krijg dezelfde waarschuwing. Ik gebruik deze compiler:

~/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)

Welk formaat moet ik gebruiken om my_int variabele af te drukken zonder waarschuwing?


Antwoord 1, autoriteit 100%

Voor int64_ttypt u:

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

voor uint64_ttyp:

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

u kunt ook PRIx64gebruiken om in hexadecimaal af te drukken.

cppreference.com heeft een volledige lijstvan beschikbare macro’s voor alle typen, inclusief intptr_t(PRIxPTR). Er zijn aparte macro’s voor scanf, zoals SCNd64.


Een typische definitie van PRIu16 is "hu", dus impliciete aaneenschakeling van strings met constante aaneenschakeling vindt plaats tijdens het compileren.

Om uw code volledig overdraagbaar te maken, moet u PRId32enzovoort gebruiken voor het afdrukken van int32_t, en "%d"of iets dergelijks voor het afdrukken van int.


Antwoord 2, autoriteit 14%

De C99-manier is

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

Of je kunt casten!

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

Als je vastzit aan een C89-implementatie (met name Visual Studio), kun je misschien een open source <inttypes.h>gebruiken (en <stdint.h>): http://code.google.com/p/msinttypes/


Antwoord 3, autoriteit 4%

Met C99 kan de lengtemodifier %jook worden gebruikt met de printf-familie van functies om waarden van het type int64_ten uint64_taf te drukken:

#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;
}

Het compileren van deze code met gcc -Wall -pedantic -std=c99levert geen waarschuwingen op en het programma drukt de verwachte uitvoer af:

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

Dit is volgens printf(3)op mijn Linux-systeem (de man-pagina zegt specifiek dat jwordt gebruikt om een conversie naar een intmax_tof uintmax_t; in mijn stdint.h worden zowel int64_tals intmax_top precies dezelfde manier getypt, en op dezelfde manier voor uint64_t). Ik weet niet zeker of dit perfect overdraagbaar is naar andere systemen.


Antwoord 4, autoriteit 3%

Afkomstig uit de embedded wereld, waar zelfs uclibc niet altijd beschikbaar is, en code zoals

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

drukt je onzin af of werkt helemaal niet — ik gebruik altijd een kleine helper, waarmee ik correct kan dumpen 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;
}

Antwoord 5, autoriteit 2%

Gebruik in Windows-omgeving

%I64d

gebruik in Linux

%lld

Antwoord 6

//VC6.0 (386 en beter)

   __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);

Met vriendelijke groet.

Other episodes