rtacconi
El estándar C99 tiene tipos enteros con tamaño de bytes como int64_t. estoy usando Windows %I64d
formato actualmente (o sin firmar %I64u
), me gusta:
#include <stdio.h>
#include <stdint.h>
int64_t my_int = 999999999999999999;
printf("This is my_int: %I64d\n", my_int);
y me sale esta advertencia del compilador:
warning: format ‘%I64d’ expects type ‘int’, but argument 2 has type ‘int64_t’
Probé 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 tener una advertencia?
ouah
Para int64_t
escribe:
#include <inttypes.h>
int64_t t;
printf("%" PRId64 "\n", t);
por uint64_t
escribe:
#include <inttypes.h>
uint64_t t;
printf("%" PRIu64 "\n", t);
también puedes usar PRIx64
para imprimir en hexadecimal.
cppreference.com tiene una lista completa de macros disponibles para todos los tipos incluyendo intptr_t
(PRIxPTR
). Hay macros separadas 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 tiempo de compilación.
Para que su código sea completamente portátil, debe usar PRId32
y así sucesivamente para imprimir int32_t
y "%d"
o similar para imprimir int
.
-
Lista completa de constantes de macro de formato: es.cppreference.com/w/cpp/types/integer
– Masud Khaari
14 mayo 2013 a las 10:45
-
Y, si usa C++ en Linux, asegúrese de
#define __STDC_FORMAT_MACROS
antes de incluirinttypes.h
.– csl
28 de noviembre de 2014 a las 8:50
-
PRId64
es una macro que se traduce internamente a"lld"
. Entonces, es tan bueno como escribirprintf("%lld\n", t);
Ver la descripción : qnx.com/developers/docs/6.5.0/…– Gaurav
14 de agosto de 2015 a las 11:32
-
@Gaurav, eso es cierto en algunas plataformas, pero no en todas. En mi máquina AMD64 Linux, por ejemplo, PRId64 se define como
ld
. La portabilidad es la razón de la macro.– Ethan T.
28 de junio de 2016 a las 15:06
-
Creo que con un poco de esfuerzo extra podrían haberlo hecho aún más desagradable.
– Pavel P.
27/10/2017 a las 23:35
pmg
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 C89 (especialmente Visual Studio), quizás pueda usar una fuente abierta <inttypes.h>
(y <stdint.h>
): http://code.google.com/p/msinttypes/
-
Cuando uso msinttypes desde el enlace code.google.com, necesito definir __STDC_FORMAT_MACROS. Consulte stackoverflow.com/questions/8132399/how-to-printf-uint64-t.
– ariscris
28 mayo 2014 a las 16:49
-
Gracias por el aviso, @ariscris. Sin embargo, parece que la macro solo se requiere para C ++. Las definiciones en el código vinculado están dentro de un
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
– pmg
28 mayo 2014 a las 17:08
pjhsea
Con C99 el %j
El modificador de longitud también se puede usar con la familia de funciones printf para imprimir valores de tipo 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;
}
Compilando este código con gcc -Wall -pedantic -std=c99
no produce advertencias y el programa imprime el resultado esperado:
a=-9223372036854775808 (0x8000000000000000)
b=9223372036854775808 (0x8000000000000000)
esto es de acuerdo a printf(3)
en mi sistema Linux (la página de manual dice específicamente que j
se utiliza para indicar una conversión a un intmax_t
o uintmax_t
; en mi stdint.h, ambos int64_t
y intmax_t
está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.
-
Si
%jd
imprime unintmax_t
la invocación correcta seríaprintf("a=%jd (0x%jx)", (intmax_t) a, (intmax_t) a)
. No hay garantía de queint64_t
yintmax_t
son del mismo tipo, y si no lo son, el comportamiento es indefinido.– usuario4815162342
25 de abril de 2013 a las 17:56
-
Puede usar de forma portátil
%jd
imprimirint64_t
valores si los convierte explícitamente enintmax_t
antes de pasarlos aprintf
:printf("a=%jd\n", (intmax_t)a)
. Esto evita la fealdad (en mi humilde opinión) de la<inttypes.h>
macros Por supuesto, esto supone que su implementación admite%jd
,int64_t
yintmax_t
todos los cuales fueron agregados por C99.–Keith Thompson
12 de agosto de 2013 a las 19:03
-
@KeithThompson ‘Fealdad’ lo está poniendo demasiado, demasiado amablemente amigo. Es absolutamente horrible. es espantoso. Es nauseabundo. Es vergonzoso es lo que es. O al menos deberían estar avergonzados, los que presentaron esto. Nunca he visto estas macros, pero haga lo que sugiere esta respuesta y los comentarios, incluidos los suyos.
– Priftan
3 de diciembre de 2019 a las 22:59
-
@Pryftan Yo no bastante encuéntrelos tan feos como usted, y no estoy del todo seguro de cómo podrían definirse de una manera menos fea sin cambios de idioma.
–Keith Thompson
4 de diciembre de 2019 a las 2:28
-
@KeithThompson Bueno, estoy agradecido de que al menos hayas puesto énfasis en la palabra ‘bastante’. Bueno, en realidad no importa. Sin embargo, no veo por qué las macros tienen que estar allí. Como dices, puedes transportarlo… Etc. Pero luego también encuentro que el aumento en la cantidad de palabras clave también se ha ido de las manos.
– Priftan
14 dic 2019 a las 20:46
Viniendo del mundo integrado, donde incluso uclibc no siempre está disponible, y código como
uint64_t myval = 0xdeadfacedeadbeef;
printf("%llx", myval);
está imprimiendo basura o no funciona en absoluto; siempre uso un pequeño ayudante, que me permite volcar correctamente 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;
}
benlong
En el entorno de Windows, utilice
%I64d
en Linux, utilice
%lld
-
%lld
es el formato paralong long int
cual es no necesariamente lo mismo queint64_t
.<stdint.h>
tiene una macro para el formato correcto paraint64_t
; ver la respuesta de ouah.–Keith Thompson
12 de agosto de 2013 a las 19:05
-
@KeithThompson Sin embargo, desde
long long
es de al menos 64 bits,printf("%lld", (long long)x);
debería funcionar, excepto quizás para -0x8000000000000000, que no podría representarse como unlong long
si ese tipo no está usando complemento a dos.– Pascal Cuoq
12 de agosto de 2013 a las 20:54
-
@PascalCuoq: Sí, debería funcionar con el elenco (y la excepción que menciona es muy poco probable, se aplica solo a un sistema que admite el complemento a dos pero no lo usa para
long long
).–Keith Thompson
12/08/2013 a las 21:10
HarshaD
Me topé con esta pregunta cuando estaba buscando una forma de mostrar un número de 64 bits en hexadecimal:
Descubrí que puedes usar:
0x%016llx
– al menos funciona con mi compilador (aarch64 GCC 7.3.0
)
-
%lld
es el formato paralong long int
cual es no necesariamente lo mismo queint64_t
.<stdint.h>
tiene una macro para el formato correcto paraint64_t
; ver la respuesta de ouah.–Keith Thompson
12 de agosto de 2013 a las 19:05
-
@KeithThompson Sin embargo, desde
long long
es de al menos 64 bits,printf("%lld", (long long)x);
debería funcionar, excepto quizás para -0x8000000000000000, que no podría representarse como unlong long
si ese tipo no está usando complemento a dos.– Pascal Cuoq
12 de agosto de 2013 a las 20:54
-
@PascalCuoq: Sí, debería funcionar con el elenco (y la excepción que menciona es muy poco probable, se aplica solo a un sistema que admite el complemento a dos pero no lo usa para
long long
).–Keith Thompson
12/08/2013 a las 21:10
//VC6.0 (386 y superior)
__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);
Saludos.
Para C++, consulte stackoverflow.com/questions/8132399/how-to-printf-uint64-t
– Antonio
23 de agosto de 2016 a las 9:02