impresión multiplataforma de enteros de 64 bits con printf

4 minutos de lectura

avatar de usuario
Andrei

En Windows, es “%I64d”. En Linux y Solaris, es “%lld”.
Si quiero escribir multiplataforma printfs que imprime long long valores: ¿cuál es una buena manera de hacerlo?

long long ll;
printf(???, ll);

  • Aparentemente necesito #si está definido (WIN32) && !definido (PRId64) \n #define PRId64 “I64d” \n #endif. Gracias a todos los que respondieron.

    – Andrei

    10 de junio de 2011 a las 5:53


  • también debe buscar en sus tipos y tener un typedef para reemplazar [u]int64_t si no están disponibles.

    – Jens Gusted

    10 de junio de 2011 a las 6:34

  • ¿Cuál es la diferencia entre entero de 64 bits y largo? Estoy leyendo el programa de otros y usan PRId64, que no entiendo.

    – 1a1a11a

    22 de marzo de 2016 a las 13:36

avatar de usuario
DigitalRoss

Hay un par de enfoques.

Podría escribir su código de manera compatible con C99 y luego proporcionar trucos específicos del sistema cuando los compiladores-escritores lo defraudaran. (Lamentablemente, eso es bastante común en C99).

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

Si uno de sus sistemas de destino se ha olvidado de implementar <inttypes.h> o se ha aflojado diabólicamente de alguna otra manera porque algunas de las funciones de tipo son opcionales, entonces solo necesita un sistema específico #define por PRId64 (o lo que sea) en ese sistema.

El otro enfoque es elegir algo que actualmente siempre esté implementado como 64 bits y sea compatible con printf, y luego emitirlo. No es perfecto, pero a menudo lo hará:

printf("My value is %10lld\n", (long long)some_64_bit_expression);

  • No dijo el tipo exacto que estaba imprimiendo, pero como otros han notado, PRId64 es específicamente para int64_t. Si utiliza <stdint.h> se supone que hay una correspondencia <inttypes.h> macro para imprimir

    – DigitalRoss

    9 de junio de 2011 a las 21:20

  • Me gustaría aceptar ambas respuestas, la de DigitalRoss y la de Random832, no sé cómo hacerlo. Solicitud de archivos en metaforo.

    – Andrei

    13 de junio de 2011 a las 20:48

  • Comentario tardío, pero me perdí que todavía necesitaba el % en la cadena antes del PRId64o bien se quejó de some_64_bit_expression ser inesperado: printf("Foo %" PRId64, some_64_bit_expression);

    – Policía en línea

    29 de noviembre de 2017 a las 16:32

Soportes de MSVC long long y ll a partir de estudio visual 2005.

Puede comprobar el valor de la _MSC_VER macro (>= 1400 para 2005), o simplemente no admite compiladores más antiguos.

No proporciona las macros C99, por lo que tendrá que enviar a long long en lugar de usar PRId64.

Esto no ayudará si está utilizando bibliotecas MSVC más antiguas con un compilador que no sea MSVC (creo que mingw, al menos, proporciona su propia versión de printf que admite ll)

  • Parece que MS agregó el ll soporte modificador para msvcrt.dll (al menos en mi caja Win7). Estoy sorprendido por esto. No parece que MinGW haya hecho nada especial para respaldarlo (y la última vez que intenté usar ll con MinGW fracasó estrepitosamente).

    – Michael Burr

    10 de junio de 2011 a las 0:30

  • Gracias. Nunca supe que MSVC era compatible con %lld.

    – Andrei

    10 de junio de 2011 a las 6:01

  • Me gustaría aceptar ambas respuestas, la de DigitalRoss y la de Random832, no sé cómo hacerlo. Solicitud de archivos en metaforo.

    – Andrei

    13 de junio de 2011 a las 20:48

avatar de usuario
Jens Gustedt

No en linux y solaris es solo por cierto que esto es lld para un tipo de 64 bits. C99 prescribe macros simples (pero feas) para hacer que estas cosas sean portátiles PRId64. Dado que algunos compiladores de Windows no siguen el estándar, es posible que no tenga suerte, lamentablemente.

Editar: En su ejemplo, está utilizando algo diferente a un número entero de 64 bits, a saber, un long long. Esto bien podría ser 128 en algunas arquitecturas. Aquí C99 tiene typedefs que te garantizan el ancho mínimo o exacto del tipo (si están implementados en la plataforma). Estos tipos se encuentran con el inttypes.h cabecera, a saber int64_t para un tipo de 64 bits de ancho fijo representado en complemento a dos. Tal vez o tal vez no su compilador de Windows tenga esto.

  • Nota la PRId64 la macro es para imprimir int64_tno long long.

    -Dietrich Epp

    9 de junio de 2011 a las 20:58

  • @Dietrich, exactamente. Interpreté el título de la pregunta como tal. Pero tienes razón, agrego un comentario sobre long long.

    – Jens Gusted

    9 de junio de 2011 a las 21:01

avatar de usuario
Aleksander Alekseev

Como alternativa, puede usar un código como este:

uint64_t currentTimeMs = ...;

printf("currentTimeMs = 0x%08x%08x\n",
            (uint32_t)(currentTimeMs >> 32),
            (uint32_t)(currentTimeMs & 0xFFFFFFFF)
    );

O tal vez:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad