Как напечатать тип int64_t в C

Стандарт C99 имеет целочисленные типы с размером байтов, такими как int64_t. Я использую следующий код:

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

и я получаю предупреждение этого компилятора:

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

Я пробовал:

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

Но я получаю такое же предупреждение. Я использую этот компилятор:

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

Какой формат следует использовать для печати переменной my_int без предупреждения?

Ответ 1

Для int64_t введите:

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

для uint64_t type:

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

вы также можете использовать PRIx64 для печати в шестнадцатеричном формате.

cppreference.com содержит полный список доступных макросов для всех типов, включая intptr_t (PRIxPTR). Для scanf существуют отдельные макросы, например SCNd64.


Типичное определение PRIu16 будет "hu", поэтому во время компиляции происходит неявное конкатенация строковой константы.

Чтобы ваш код был полностью переносимым, вы должны использовать PRId32 и т.д. для печати int32_t и "%d" или аналогичных для печати int.

Ответ 2

Путь C99 -

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

Или вы можете использовать!

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

Если вы застряли в реализации C89 (в частности, Visual Studio), вы можете использовать открытый источник <inttypes.h><stdint.h>): http://code.google.com/p/msinttypes/

Ответ 3

С C99 модификатор длины %j также может использоваться с семейством функций printf для типов int64_t и 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;
}

Компиляция этого кода с помощью gcc -Wall -pedantic -std=c99 не вызывает никаких предупреждений, и программа печатает ожидаемый результат:

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

Это соответствует printf(3) в моей Linux-системе (в man-странице указано, что j используется для указания преобразования в intmax_t или uintmax_t; в моем stdint.h оба int64_t и intmax_t точно подобран, и аналогично для uint64_t). Я не уверен, что это совершенно портативно для других систем.

Ответ 4

Исходя из встроенного мира, где даже uclibc не всегда доступен, и код вроде

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

печатает вас дерьмо или вообще не работает - я всегда использую крошечный помощник, который позволяет мне правильно сбрасывать 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;
}

Ответ 5

В среде Windows используйте

%I64d

в Linux, используйте

%lld

Ответ 6

//VC6.0 (386 и лучше)

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

С уважением.