Я пытаюсь напечатать такие типы, как off_t
и size_t
. Каков правильный дескриптор для printf()
, который переносится?
Или существует ли совершенно другой способ печати этих переменных?
Я пытаюсь напечатать такие типы, как off_t
и size_t
. Каков правильный дескриптор для printf()
, который переносится?
Или существует ли совершенно другой способ печати этих переменных?
Вы можете использовать z
для size_t и t
для ptrdiff_t, как в
printf("%zu %td", size, ptrdiff);
Но моя справочная страница говорит, что в какой-то более старой библиотеке использовался символ, отличный от z
и не рекомендует его использовать. Тем не менее, он стандартизирован (по стандарту C99). Для тех intmax_t
и int8_t
из stdint.h
и т.д. Есть макросы, которые вы можете использовать, как сказал другой ответ:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Они перечислены в inttypes.h
.
Лично я просто приведу значения к unsigned long
или long
как рекомендует другой ответ. Если вы используете C99, то вы можете (и, конечно, должны) привести к unsigned long long
или long long
и использовать %llu
или %lld
соответственно.
Чтобы напечатать off_t
:
printf("%jd\n", (intmax_t)x);
Чтобы напечатать size_t
:
printf("%zu\n", x);
Чтобы напечатать ssize_t
:
printf("%zd\n", x);
См. 7.19.6.1/7 в стандарте C99 или более удобную документацию POSIX для кодов форматирования:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Если ваша реализация не поддерживает эти коды форматирования (например, из-за того, что вы находитесь на C89), у вас есть немного проблемы, поскольку AFAIK в C89 не имеют целочисленных типов, которые имеют коды форматирования и гарантированы быть такими же большими, как эти типы. Поэтому вам нужно сделать что-то конкретное для реализации.
Например, если ваш компилятор имеет long long
, а ваша стандартная библиотека поддерживает %lld
, вы можете с уверенностью ожидать, что это будет вместо intmax_t
. Но если это не так, вам придется вернуться к long
, что может быть неудачно для некоторых других реализаций, потому что оно слишком мало.
Для Microsoft ответ отличается. VS2013 в значительной степени совместим с C99, но "префиксы [t] he hh, j, z и t length не поддерживаются". Для size_t "то есть без знака __int32 на 32-битных платформах без знака __int64 на 64-битных платформах" используйте префикс я (заглавный глаз) с спецификатором типа o, u, x или X. См. спецификацию размера VS2013
Как и для off_t, он определен как длинный в VC\include\sys\types.h.
Какую версию C вы используете?
В C90 стандартная практика заключается в том, чтобы придать подписанному или unsigned long, в зависимости от ситуации, и напечатать соответствующим образом. Я видел% z для size_t, но Harbison и Steele не упоминают об этом под printf(), и в любом случае это не поможет вам с ptrdiff_t или что-то еще.
В C99 различные типы _t поставляются со своими собственными макросами printf, поэтому что-то вроде "Size is " FOO " bytes."
Я не знаю деталей, но эта часть довольно большого числового формата включает файл.
Вы хотите использовать макросы форматирования из inttypes.h.
Смотрите этот вопрос: Строка формата кросс-платформы для переменных типа size_t?
Глядя на man 3 printf
на Linux, OS X и OpenBSD, все показывают поддержку %z
для size_t
и %t
для ptrdiff_t
(для C99), но ни одна из них не упоминает off_t
. Предложения в дикой природе обычно предлагают преобразование %u
для off_t
, которое является "достаточно правильным", насколько я могу судить (оба unsigned int
и off_t
одинаково различаются между 64-битными и 32-битными системами).
Я видел этот пост как минимум дважды, потому что принятый ответ мне трудно вспомнить (я редко использую флаги z
или j
, и они, кажется, не независимые от платформы).
стандарт никогда точно не говорит о точной длине данных size_t
, поэтому я предлагаю вам сначала проверить длину size_t
на вашей платформе, а затем выбрать один из их:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
И я предлагаю использовать типы stdint
вместо необработанных типов данных для согласованности.
Как я помню, единственный переносимый способ сделать это - это привести результат к "unsigned long int" и использовать %lu
.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
Пожалуйста, используйте% lu. Off_t не имеет знака long.
используйте "% zo" для off_t. (Восьмеричное) или "% zu" для десятичного числа.