Cómo imprimir de forma portátil un tipo int64_t en C

Resuelto rtacconi asked hace 12 años • 7 respuestas

El estándar C99 tiene tipos de números enteros con tamaño de bytes como int64_t. %I64dActualmente estoy usando el formato de Windows (o sin firmar %I64u), como:

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

y recibo esta advertencia del compilador:

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

Lo intenté con:

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

Pero recibo la misma advertencia. Estoy usando este compilador:

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

¿Qué formato debo usar para imprimir la variable my_int sin recibir una advertencia?

rtacconi avatar Feb 10 '12 16:02 rtacconi
Aceptado

Por int64_ttipo:

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

por uint64_ttipo:

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

También puedes utilizar PRIx64para imprimir en hexadecimal.

cppreference.com tiene una lista completa de macros disponibles para todos los tipos, incluida intptr_t( PRIxPTR). Hay macros independientes para scanf, como SCNd64.


Una definición típica de PRIu16 sería "hu", por lo que la concatenación implícita de constantes de cadena ocurre en el momento de la compilación.

Para que su código sea completamente portátil, debe usar PRId32etc para imprimir int32_ty "%d"similares para imprimir int.

ouah avatar Feb 10 '2012 09:02 ouah

La forma C99 es

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

¡O podrías lanzar!

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

Si está atascado con una implementación de C89 (en particular, Visual Studio), tal vez pueda usar un código abierto <inttypes.h>(y <stdint.h>): http://code.google.com/p/msinttypes/

pmg avatar Feb 10 '2012 09:02 pmg

Con C99, el %jmodificador de longitud también se puede utilizar con la familia de funciones printf para imprimir valores de tipo int64_ty 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;
}

La compilación de este código gcc -Wall -pedantic -std=c99no genera advertencias y el programa imprime el resultado esperado:

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

Esto es de acuerdo con printf(3)mi sistema Linux (la página de manual dice específicamente que jse usa para indicar una conversión a intmax_tor uintmax_t; en mi stdint.h, ambos int64_ty intmax_testán tipificados exactamente de la misma manera, y de manera similar para uint64_t). No estoy seguro de si esto es perfectamente portátil a otros sistemas.

pjhsea avatar Apr 25 '2013 17:04 pjhsea

Viniendo del mundo integrado, donde incluso uclibc no siempre está disponible y códigos como

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

¿Estás imprimiendo una mierda o no funciona en absoluto? Siempre uso un pequeño ayudante que me permite volcar correctamente uint64_t hexadecimal:

#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;
}
ataraxic avatar Nov 20 '2015 19:11 ataraxic