419 Stimmen

Wie man einen int64_t-Typ in C portabel ausgibt

C99-Standard hat Integer-Typen mit Bytes Größe wie int64_t. Ich verwende die Windows %I64d Format derzeit (oder vorzeichenlos %I64u ), wie:

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

und ich erhalte diese Compiler-Warnung:

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

Ich habe es mit versucht:

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

Aber ich bekomme die gleiche Warnung. Ich verwende diesen 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)

Welches Format sollte ich verwenden, um die Variable my_int ohne eine Warnung zu drucken?

596voto

ouah Punkte 138337

Für int64_t Typ:

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

für uint64_t Typ:

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

können Sie auch verwenden PRIx64 in hexadezimaler Form zu drucken.

cppreference.com hat eine vollständige Liste der verfügbaren Makros für alle Typen einschließlich intptr_t ( PRIxPTR ). Es gibt separate Makros für scanf, wie SCNd64 .


Eine typische Definition von PRIu16 wäre "hu" so dass die implizite Verkettung von Zeichenketten und Konstanten zur Kompilierungszeit erfolgt.

Damit Ihr Code vollständig portabel ist, müssen Sie PRId32 und so weiter zum Drucken int32_t であり、また "%d" oder ähnliches zum Drucken int .

83voto

pmg Punkte 102904

Der C99-Weg ist

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

Oder Sie können werfen!

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

Wenn Sie auf eine C89-Implementierung angewiesen sind (insbesondere Visual Studio), können Sie vielleicht eine Open-Source <inttypes.h> (und <stdint.h> ): http://code.google.com/p/msinttypes/

25voto

pjhsea Punkte 801

Mit C99 wird die %j Längenmodifikator kann auch mit der printf-Funktionsfamilie verwendet werden, um Werte des Typs int64_t y 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;
}

Kompilieren dieses Codes mit gcc -Wall -pedantic -std=c99 erzeugt keine Warnungen, und das Programm gibt die erwartete Ausgabe aus:

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

Dies ist laut printf(3) auf meinem Linux-System (die Manpage sagt ausdrücklich, dass j wird verwendet, um eine Umwandlung in eine intmax_t ou uintmax_t in meiner stdint.h, beide int64_t y intmax_t sind auf genau dieselbe Weise typisiert, und ähnlich verhält es sich mit uint64_t ). Ich bin nicht sicher, ob das auf andere Systeme übertragbar ist.

19voto

ataraxic Punkte 1907

Da ich aus der Embedded-Welt komme, in der selbst uclibc nicht immer verfügbar ist, und Code wie

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

druckt Sie Mist oder überhaupt nicht funktioniert -- ich benutze immer einen kleinen Helfer, der mir erlaubt, richtig uint64_t hex zu dumpen:

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

13voto

benlong Punkte 650

In einer Windows-Umgebung verwenden Sie

%I64d

in Linux, verwenden Sie

%lld

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X