Как вы форматируете unsigned long long int, используя printf?

#include <stdio.h>
int main() {
    unsigned long long int num = 285212672; //FYI: fits in 29 bits
    int normalInt = 5;
    printf("My number is %d bytes wide and its value is %ul. A normal number is %d.\n", sizeof(num), num, normalInt);
    return 0;
}

Вывод:

My number is 8 bytes wide and its value is 285212672l. A normal number is 0.

Я предполагаю, что этот неожиданный результат от печати unsigned long long int. Как вам printf()Согласовать unsigned long long int?

5.08.2008 20:59:29
Я только что скомпилировал ваш код (с% llu) с помощью gcc, и вывод был правильным. Вы передаете какие-либо параметры компилятору?
Juan 7.08.2008 23:13:28
Обратите внимание, что newlib от samsung bada, похоже, не поддерживает "% lld": developer.bada.com/forum/…
RzR 7.10.2010 10:42:46
hippietrail 3.04.2011 09:51:50
Я бы предложил использовать stdint.h и точно указать количество бит в вашей переменной. Мы все еще находимся в переходном периоде между 32- и 64-битными архитектурами, и «unsigned long long int» не означает одно и то же для обоих.
BD at Rivenhill 13.05.2011 22:19:57
12 ОТВЕТОВ
РЕШЕНИЕ

Используйте модификатор long (long) для ll (el-el) с преобразованием u (без знака). (Работает в windows, GNU).

printf("%llu", 285212672);
475
25.04.2012 22:13:14
Или, если быть точным, это для GNU libc, и не работает с Microsoft C времени выполнения.
Mark Baker 8.10.2008 09:35:02
Это не Linux / UNIX, модификатор длины "ll" был добавлен в Standard C в C99, если он не работает в "Microsoft C", то это потому, что они не соответствуют стандартам.
Robert Gamble 17.10.2008 04:46:31
У меня работает в VS2008. Более того, насколько я помню, компилятор MS C (когда он настроен на прямую компиляцию C) должен быть совместим с C90 по своему дизайну; C99 представил некоторые вещи, которые понравились не всем.
スーパーファミコン 11.10.2009 20:57:26
Здесь нужно помнить одну вещь: если вы передаете несколько long longаргументов printfи используете неправильный формат для одного из них, скажем, %dвместо %lld, то даже аргументы, напечатанные после неправильного, могут быть полностью отключены (или даже могут привести printfк сбою). ). По сути, переменные аргументы передаются в printf без какой-либо информации о типе, поэтому, если строка формата неверна, результат непредсказуем.
dmitrii 23.01.2012 23:10:09
В интервью Херд Саттер сказал, что клиенты Microsoft не просят C99, поэтому их чистый компилятор C был заморожен на C90. Это применимо, если вы компилируете как C. Если вы компилируете как C ++, как уже отмечали другие, у вас все будет хорошо.
ahcox 19.09.2012 20:29:40

Нестандартные вещи всегда странные :)

для длинной длинной части под GNU это L, llилиq

и под окнами я считаю, что это llтолько

1
5.08.2008 21:03:07

Ну, один из способов - это скомпилировать его как x64 с VS2008

Это работает так, как вы ожидаете:

int normalInt = 5; 
unsigned long long int num=285212672;
printf(
    "My number is %d bytes wide and its value is %ul. 
    A normal number is %d \n", 
    sizeof(num), 
    num, 
    normalInt);

Для 32-битного кода нам нужно использовать правильный спецификатор формата __int64% I64u. Так и становится.

int normalInt = 5; 
unsigned __int64 num=285212672;
printf(
    "My number is %d bytes wide and its value is %I64u. 
    A normal number is %d", 
    sizeof(num),
    num, normalInt);

Этот код работает как для 32-, так и для 64-битных компиляторов VS.

0
25.06.2012 16:23:00
Попробуйте использовать действительное 64-разрядное число вместо «285212672», и я не верю, что первый пример работает правильно, скомпилированный для любой цели.
dyasta 13.10.2018 18:59:25

Вы можете попробовать использовать библиотеку inttypes.h, которая предоставляет вам такие типы, как int32_t, int64_tи uint64_tт. Д. Затем вы можете использовать ее макросы, такие как:

uint64_t x;
uint32_t y;

printf("x: %"PRId64", y: %"PRId32"\n", x, y);

Это «гарантированно» не даст вам таких же проблем, как longи unsigned long longт. Д., Так как вам не нужно угадывать, сколько битов в каждом типе данных.

88
4.09.2010 19:58:07
где это PRId64, PRId32определенные макросы?
happy_marmoset 12.12.2013 12:31:59
@happy_marmoset: они определены вinttypes.h
Nathan Fellman 12.12.2013 14:49:24
Я думаю, что вам нужно PRIu64и PRIu32для целых чисел без знака.
Lasse Kliemann 3.06.2016 15:08:35
Это inttypes.hстандарт? Не будет ли это stdint.h?
MD XF 22.05.2017 21:20:46
Обратите внимание, что эти типы точной ширины являются необязательными , поскольку существуют архитектуры, которые не имеют целочисленных типов с такой точной шириной. Только leastXи fastXтипы (которые на самом деле может быть шире , чем указано иное) являются обязательными.
DevSolar 9.07.2018 15:01:42

Это связано с тем, что% llu не работает должным образом в Windows и% d не может обрабатывать 64-битные целые числа. Вместо этого я предлагаю использовать PRIu64, и вы обнаружите, что он также переносим на Linux.

Попробуйте это вместо этого:

#include <stdio.h>
#include <inttypes.h>

int main() {
    unsigned long long int num = 285212672; //FYI: fits in 29 bits
    int normalInt = 5;
    /* NOTE: PRIu64 is a preprocessor macro and thus should go outside the quoted string. */
    printf("My number is %d bytes wide and its value is %" PRIu64 ". A normal number is %d.\n", sizeof(num), num, normalInt);
    return 0;
}

Вывод

My number is 8 bytes wide and its value is 285212672. A normal number is 5.
37
27.08.2018 19:08:36
+1 за ссылку на PRIu64, которую я никогда не видел, но она не выглядит переносимой для 64-битного Linux (по крайней мере), потому что PRIu64 расширяется до «lu» вместо «llu».
BD at Rivenhill 13.05.2011 22:15:30
И почему это было бы плохо? Long - это 64-битное значение в 64-битной Linux, как и во всех других ОС, кроме Windows.
Ringding 4.03.2012 15:06:51
@BDatRivenhill Linux / Unix использует LP64, в котором длина составляет 64 бита
phuclv 16.04.2014 12:51:32
однако, чтобы сделать его более переносимым, используйте int64_tвместо этого, потому что могут быть некоторые реализации с длинным длинным большим, чем длинный
phuclv 21.01.2015 04:12:40
это должно наверх! - одно небольшое обновление: ошибка: неверный суффикс на литерале; C ++ 11 требует пробела между литералом и идентификатором [-Wreserved-user-define-literal]
tofutim 27.08.2018 19:05:49

В Linux это есть, %lluа в Windows это%I64u

Хотя я обнаружил, что это не работает в Windows 2000, там, похоже, есть ошибка!

14
13.11.2015 09:42:28
с Windows (или, по крайней мере, с компилятором Microsoft C для Windows) есть также% I64d,% I32u и% I32d
JustJeff 6.09.2009 14:55:40
Какое это имеет отношение к Windows 2000? Библиотека C - это та, которая обрабатывает printf.
CMircea 8.05.2010 18:00:37
Как раз то, что я заметил. Я написал приложение, которое использовало эту конструкцию, и оно отлично работало на WinXP, но плюнуло на Win2k. Может быть, это как-то связано с системным вызовом, который библиотека C делает с ядром, может быть, это как-то связано с Unicode, кто знает. Я помню, что мне приходилось обходить его, используя _i64tot () или что-то в этом роде.
Adam Pierce 11.05.2010 06:21:32
Похоже, MS снова использует свою «свободу инноваций» ... ;-)
Dronz 12.11.2012 06:20:56
Вероятно, проблема Win2k / Win9x связана с тем, что unsigned long longтип данных является относительно новым (в то время, со стандартом C99), но компиляторами C (включая MinGW / GCC), использующими старую среду выполнения Microsoft C, которая поддерживала только спецификацию C89. У меня есть доступ только к действительно старым и достаточно свежим документам по Windows API. Так что сложно сказать, когда именно I64uбыла добавлена ​​поддержка. Но это похоже на эпоху XP.
veganaiZe 18.06.2018 17:57:20

Для длительного (или __int64) использования MSVS вы должны использовать% I64d:

__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b);    //I is capital i
39
6.09.2009 14:36:41

Скомпилируйте его как x64 с VS2005:

% llu работает хорошо.

8
11.10.2012 06:23:13

%d-> для int

%u-> для unsigned int

%ld-> для long int

%lu-> для unsigned long int

%lld-> для long long int

%llu-> для unsigned long long int

72
6.04.2018 05:21:09
Существует ли спецификатор формата, например количество отображаемых цифр, выравнивание по левому или правому краю для% lld или% llu?
Asam Padeh 30.09.2019 23:10:25

Hex:

printf("64bit: %llp", 0xffffffffffffffff);

Вывод:

64bit: FFFFFFFFFFFFFFFF
1
26.07.2015 09:57:06
Очень хорошо! мне было интересно, как я могу получить его в шестнадцатеричном представлении
0xAK 12.08.2016 22:54:52
Но почти все компиляторы C ++ и C выдают предупреждение: warning: используйте модификатор длины 'll' с символом типа 'p' [-Wformat =]
Seshadri R 16.11.2017 09:00:36
этот совершенно неверный ответ имеет двусмысленное поведение и даже не начинает отвечать на вопрос .
Antti Haapala 18.12.2019 21:10:38
@AnttiHaapala Вы говорите, что этот ответ полностью нарушен двусмысленным поведением, можете ли вы уточнить или я просто удалил его? Или оставить это как хороший плохой пример?
lama12345 19.12.2019 09:46:37

В дополнение к тому, что люди написали много лет назад:

  • Вы можете получить эту ошибку в gcc / mingw:

main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]

printf("%llu\n", k);

Тогда ваша версия mingw не по умолчанию c99. Добавьте этот флаг компилятора: -std=c99.

3
17.01.2016 12:27:29

По-видимому, никто не придумал мультиплатформенное * решение в течение более десяти лет с [2008 года], поэтому я добавлю свое

1
22.03.2019 19:55:47
Я не имею lltoa.
Antti Haapala 18.12.2019 21:12:07