Стандарт 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 без предупреждения?
Ответы:
Для
int64_t
типа:для
uint64_t
типа:Вы также можете использовать
PRIx64
для печати в шестнадцатеричном формате.cppreference.com имеет полный список доступных макросов для всех типов, включая
intptr_t
(PRIxPTR
). Есть отдельные макросы для scanf, вродеSCNd64
.Типичное определение PRIu16 было бы таким
"hu"
, поэтому неявная конкатенация строк и констант происходит во время компиляции.Чтобы ваш код был полностью переносимым, вы должны использовать
PRId32
и т. Д. Для печатиint32_t
,"%d"
или аналогичные для печатиint
.источник
#define __STDC_FORMAT_MACROS
перед включениемinttypes.h
.PRId64
это макрос, который внутренне переводится в"lld"
. Итак, это так же хорошо, как писать.printf("%lld\n", t);
См. Описание: qnx.com/developers/docs/6.5.0/…ld
. Портативность является причиной для макроса.Путь С99
Или вы могли бы бросить!
Если вы застряли с реализацией C89 (в частности, с Visual Studio), вы можете использовать открытый исходный код
<inttypes.h>
(и<stdint.h>
): http://code.google.com/p/msinttypes/источник
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
С C99
%j
модификатор длины также может использоваться с семейством функций printf для вывода значений типаint64_t
иuint64_t
:Компиляция этого кода с не
gcc -Wall -pedantic -std=c99
производит предупреждений, и программа выводит ожидаемый результат:Это соответствует
printf(3)
моей системе Linux (на странице man конкретно указано, чтоj
она используется для обозначения преобразования вintmax_t
илиuintmax_t
; в моем stdint.h обаint64_t
иintmax_t
typedef'd точно таким же образом и аналогично дляuint64_t
). Я не уверен, что это идеально подходит для других систем.источник
%jd
prnts anintmax_t
, правильный вызов будетprintf("a=%jd (0x%jx)", (intmax_t) a, (intmax_t) a)
. Там нет никакой гарантии , чтоint64_t
иintmax_t
того же типа, и если они не являются, поведение не определено.%jd
для печатиint64_t
значения , если вы явно преобразовать ихintmax_t
перед передачей ихprintf
:printf("a=%jd\n", (intmax_t)a)
. Это позволяет избежать (ИМХО) уродства<inttypes.h>
макросов. Конечно, это предполагает, что ваша реализация поддерживает%jd
,int64_t
иintmax_t
все они были добавлены C99.Исходя из встроенного мира, где даже uclibc не всегда доступен, и код вроде
uint64_t myval = 0xdeadfacedeadbeef; printf("%llx", myval);
печатает у вас дерьмо или не работает вообще - я всегда использую крошечный помощник, который позволяет мне правильно записать шестнадцатеричный uint64_t:
источник
В среде Windows используйте
в Linux используйте
источник
%lld
это формат дляlong long int
, который не обязательно совпадает сint64_t
.<stdint.h>
есть макрос для правильного формата дляint64_t
; посмотри ответ Оах .long long
он по крайней мере 64-разрядный, онprintf("%lld", (long long)x);
должен работать, за исключением, возможно, -0x8000000000000000, который не может быть представлен как,long long
если этот тип не использует дополнение до двух.long long
).//VC6.0 (386 и лучше)
С уважением.
источник