Как мне печатать такие типы, как off_t и size_t?

Я пытаюсь напечатать такие типы, как off_t и size_t. Каков правильный дескриптор для printf(), который переносится?

Или существует ли совершенно другой способ печати этих переменных?

Ответ 1

Вы можете использовать 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 соответственно.

Ответ 2

Чтобы напечатать 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, что может быть неудачно для некоторых других реализаций, потому что оно слишком мало.

Ответ 3

Для 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.

Ответ 4

Какую версию C вы используете?

В C90 стандартная практика заключается в том, чтобы придать подписанному или unsigned long, в зависимости от ситуации, и напечатать соответствующим образом. Я видел% z для size_t, но Harbison и Steele не упоминают об этом под printf(), и в любом случае это не поможет вам с ptrdiff_t или что-то еще.

В C99 различные типы _t поставляются со своими собственными макросами printf, поэтому что-то вроде "Size is " FOO " bytes." Я не знаю деталей, но эта часть довольно большого числового формата включает файл.

Ответ 6

Глядя на 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-битными системами).

Ответ 7

Я видел этот пост как минимум дважды, потому что принятый ответ мне трудно вспомнить (я редко использую флаги z или j, и они, кажется, не независимые от платформы).

стандарт никогда точно не говорит о точной длине данных size_t, поэтому я предлагаю вам сначала проверить длину size_t на вашей платформе, а затем выбрать один из их:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

И я предлагаю использовать типы stdint вместо необработанных типов данных для согласованности.

Ответ 8

Как я помню, единственный переносимый способ сделать это - это привести результат к "unsigned long int" и использовать %lu.

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));

Ответ 9

Пожалуйста, используйте% lu. Off_t не имеет знака long.

Ответ 10

используйте "% zo" для off_t. (Восьмеричное) или "% zu" для десятичного числа.