межплатформенная печать 64-битных целых чисел с помощью printf - PullRequest
26 голосов
/ 10 июня 2011

В Windows это "% I64d".В Linux и Solaris это "% lld".
Если я хочу написать кроссплатформенный printfs, который печатает long long значений: что является хорошим способом сделать это?

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

Ответы [ 4 ]

39 голосов
/ 10 июня 2011

Существует несколько подходов.

Вы можете написать свой код в соответствии с C99, а затем предоставить системные хаки, когда авторы компиляторов подведут вас.(К сожалению, это довольно часто встречается в C99.)

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

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

Если одна из ваших целевых систем пренебрегла реализацией <inttypes.h> или каким-то иным образом извергнула слабость, потому что некоторые функции типа являются необязательными,тогда вам просто нужна системная #define для PRId64 (или что-то еще) в этой системе.

Другой подход заключается в выборе чего-то, что в настоящее время всегда реализовано как 64-битное и поддерживается printf,а затем снимали.Не идеально, но часто бывает так:

printf("My value is %10lld\n", (long long)some_64_bit_expression);
2 голосов
/ 10 июня 2011

MSVC поддерживает long long и ll начиная с Visual Studio 2005 .

Можно проверить значение макроса _MSC_VER (>= 1400для 2005) или просто не поддерживают более старые компиляторы.

Он не предоставляет макросы C99, поэтому вам придется приводить к long long вместо использования PRId64.

Это не поможет, если вы используете старые библиотеки MSVC с компилятором, отличным от MSVC (я думаю, что mingw, по крайней мере, предоставляет свою собственную версию printf, которая поддерживает ll)

1 голос
/ 10 июня 2011

Нет на Linux и Solaris, это только случайно, что это lld для 64-битного типа. C99 предписывает простые (но ужасные) макросы, чтобы сделать эти вещи переносимыми PRId64. Поскольку некоторые компиляторы Windows не следуют стандарту, вам, к сожалению, не повезло.

Редактировать: В вашем примере вы используете нечто иное, чем 64-битное целое число, а именно long long. Это может быть 128 на некоторых архитектурах. Здесь C99 имеет typedef s, которые гарантируют вам минимальную или точную ширину типа (если они реализованы на платформе). Эти типы можно найти с заголовком inttypes.h, а именно int64_t для 64-битного типа с фиксированной шириной, представленного в дополнении к двум. Может быть, а может и нет, ваш компилятор Windows имеет это.

0 голосов
/ 03 января 2016

В качестве альтернативы вы можете использовать такой код:

uint64_t currentTimeMs = ...;

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

Или, может быть:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...