Вопрос

Я пытаюсь напечатать такие типы, как 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] HH, J, Z и префиксы длины T не поддерживаются». Для size_t ", то есть unsigned __int32 на 32-разрядных платформах, unsigned __int64 на 64-битных платформах" Используйте префикс I (Capital Eye) с типом спецификатора O, U, X или X. См. спецификацию размера VS2013.

Что касается off_t, то он определен как long в VC\include\sys ypes.h.

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

В C90 стандартной практикой является приведение к знаковому или беззнаковому длинному типу, в зависимости от ситуации, и печать соответственно.Я видел %z для size_t, но Харбисон и Стил не упоминают об этом в 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));

используйте «%zo» для off_t.(восьмиугольный) или «%Zu» для десятичных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top