Какой аргумент для printf, который форматирует long?


Ответы:


634

Поместите l(строчная буква L) непосредственно перед спецификатором.

unsigned long n;
long m;

printf("%lu %ld", n, m);

14
printf("%ld", ULONG_MAX)выводит значение как -1. Должно быть printf("%lu", ULONG_MAX)для unsigned long, как описано @Blorgbeard ниже.
jammus

2
На самом деле, вы должны изменить это %ld, чтобы быть более гармоничным с вопросом OP.
Доктор Беко

Да, доктор Беко; далее, просто %lсрабатываетwarning: unknown conversion type character 0x20 in format [-Wformat]
Патрицио Бертони


73

На большинстве платформ, longи intимеют тот же размер (32 бит). Тем не менее, он имеет свой собственный спецификатор формата:

long n;
unsigned long un;
printf("%ld", n); // signed
printf("%lu", un); // unsigned

Для 64 битов вы бы хотели long long:

long long n;
unsigned long long un;
printf("%lld", n); // signed
printf("%llu", un); // unsigned

Да, и, конечно, в Windows все по-другому:

printf("%l64d", n); // signed
printf("%l64u", un); // unsigned

Часто, когда я печатаю 64-битные значения, бывает полезно напечатать их в шестнадцатеричном формате (обычно с такими большими числами, они являются указателями или битовыми полями).

unsigned long long n;
printf("0x%016llX", n); // "0x" followed by "0-padded", "16 char wide", "long long", "HEX with 0-9A-F"

напечатает:

0x00000000DEADBEEF

Кстати, «long» уже не так много значит (в основном x64). "int" - это int размер платформы по умолчанию, обычно 32 бита. «длинный» обычно одинакового размера. Тем не менее, они имеют различную семантику переносимости на старых платформах (и современных встроенных платформах!). «long long» - это 64-битное число, которое обычно используют люди, если они действительно не знают, что делают, редактируя кусок переносимого кода на x-платформе. Даже тогда они, вероятно, использовали бы вместо этого макрос для захвата семантического значения типа (например, uint64_t).

char c;       // 8 bits
short s;      // 16 bits
int i;        // 32 bits (on modern platforms)
long l;       // 32 bits
long long ll; // 64 bits 

В свое время «int» был 16 бит. Можно подумать, что теперь это будет 64 бита, но нет, это вызвало бы безумные проблемы с переносимостью. Конечно, даже это упрощение тайной и богатой истории правды. Смотрите вики: целое число


@ ММ Я уточнил свой ответ, чтобы избежать путаницы.
Дейв Допсон

4
Просто для пояснения: существует больше архитектур, чем x86 и x64, и в этих архитектурах char, short, int, long и long long имеют разные значения. Например, 32-битный MCU с 16-битным выравниванием памяти может использовать: char = short = int = 16 бит; long = 32 бита; long long = 64 бита
AndresR

1
@AndresR - безусловно, и это очень важно для людей, которые занимаются встроенным программированием (я однажды создал модуль ядра для дымовой сигнализации). Пожалейте эти бедные души, когда они пытаются использовать код, который не был написан для переносимости.
Дейв Допсон

Я не уверен, что «большинство платформ имеют longразмер 32», все еще верно. Например, я на Oracle Linux x86_64 / amd64, и с составляет 8 байт. nvcclong
ragerdl

«О, и, конечно, в Windows все по-другому». Есть ли кроссплатформенное решение?
Аарон Франке

17

Это зависит, если вы имеете в виду unsigned long, то форматирующий символ "%lu". Если вы имеете в виду подписанный длинный символ форматирования "%ld".



12

Если вы хотите печатать, unsigned long longкак я, используйте:

unsigned long long n;
printf("%llu", n);

Для всех других комбинаций, я полагаю, вы используете таблицу из руководства printf , взяв строку, а затем метку столбца для любого типа, который вы пытаетесь напечатать (как я делал printf("%llu", n)выше).


0

Я думаю, что для окончательного ответа на этот вопрос потребуется знать имя и версию компилятора, который вы используете, и платформу (тип процессора, ОС и т. Д.), Для которой он компилируется.


Ваш ответ должен быть комментарием, а не ответом сам по себе.
Хайме
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.