Как отформатировать 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?

См. Также stackoverflow.com/questions/5140871/sprintf-for-unsigned-int‌ 64

hippietrail 03.04.2011 13:51

Я бы предложил использовать stdint.h и указать количество бит в вашей переменной. Мы все еще находимся в периоде перехода между 32- и 64-битными архитектурами, и «unsigned long long int» не означает одно и то же для обеих.

BD at Rivenhill 14.05.2011 02:19

Я только что скомпилировал ваш код (с% llu) с помощью gcc, и результат был правильным. Вы передаете какие-либо параметры компилятору?

Juan 08.08.2008 03:13

Обратите внимание, что новая библиотека samsung bada, похоже, не поддерживает "% lld": developer.bada.com/forum/…

RzR 07.10.2010 14:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
395
4
809 580
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Ответ принят как подходящий

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

printf("%llu", 285212672);

Или, если быть точным, это для GNU libc и не работает со средой выполнения Microsoft C.

Mark Baker 08.10.2008 13:35

Это не Linux / UNIX, модификатор длины "ll" был добавлен к стандарту C в C99, если он не работает в "Microsoft C", то это потому, что они не соответствуют стандартам.

Robert Gamble 17.10.2008 08:46

Работает в Turbo C++ в Windows

Patrick McDonald 21.02.2009 06:43

У меня работает в VS2008. Более того, насколько я помню, компилятор MS C (когда он настроен для компиляции прямого C) должен быть совместим с C90 по дизайну; C99 представил некоторые вещи, которые понравились не всем.

スーパーファミコン 12.10.2009 00:57

Здесь следует иметь в виду, что если вы передаете несколько аргументов long long в printf и используете неправильный формат для одного из них, скажем %d вместо %lld, тогда даже аргументы, напечатанные после, неправильный, могут быть полностью отключены (или даже вызвать сбой printf). По сути, переменные аргументы передаются в printf без какой-либо информации о типе, поэтому, если строка формата неверна, результат непредсказуем.

dmitrii 24.01.2012 03:10

Слышал, как Херб Саттер сказал в интервью, что клиенты Microsoft не просят C99, поэтому их компилятор на чистом C был заморожен на C90. Это применимо, если вы компилируете как C. Если вы компилируете как C++, как другие отмечали выше, все будет в порядке.

ahcox 20.09.2012 00:29

Я не понимаю, почему такой ответ еще не был принят.

0decimal0 23.06.2013 12:08

все меняется на 64-битной машине

Antarus 10.07.2013 14:20

Использование компилятора Cygwin, который выполняет кросс-компиляцию в x86_64 (x86_64-w64-mingw32-g ++)% lx с длинным длинным беззнаковым int, дает ошибку о том, что формат и тип не совпадают, и использование% llx с той же переменной и тот же компилятор выдает ошибку% llx - неизвестный формат. И на самом деле переменная - это pthread_t. Так что он не «работает в Windows / GNU», и проблема не в том, что это компилятор Microsoft.

cardiff space man 06.04.2014 10:02

Для вывода в шестнадцатеричном формате длинное число без знака будет напечатано с% I64x. Практически переносимый способ - привести число к intmax_t и использовать PRIXMAX. А чтобы использовать PRIXMAX или что-то подобное с C++ в компиляторе GNU, вам нужно #define __STDC_FORMAT_MACROS. И в условиях, которые я описываю, определение PRIXMAX, которое я получаю, кажется неправильным, и мне нужно принудительно установить% I64X, который работает.

cardiff space man 06.04.2014 10:26

Почему не ull вместо llu?

pmor 02.06.2020 23:04

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

на длинную длинную порцию под GNU это L, ll или q

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

Ну, один из способов - скомпилировать его как 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.

Попробуйте использовать реальное 64-битное число вместо «285212672», и я не верю, что первый пример работает правильно, скомпилированный для какой-либо цели.

dyasta 13.10.2018 21:59

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

где эти макросы PRId64, PRId32 определены?

happy_marmoset 12.12.2013 16:31

@happy_marmoset: они определены в inttypes.h

Nathan Fellman 12.12.2013 18:49

Я думаю, вам нужны PRIu64 и PRIu32 для целых чисел без знака.

Lasse Kliemann 03.06.2016 18:08

Стандарт inttypes.h? Разве это не было бы stdint.h?

MD XF 23.05.2017 00:20

Ints есть в обоих, inttypes также содержат bools, которые можно найти в stdbool.h

user2316602 11.07.2017 15:44

Обратите внимание, что этими типами точной ширины являются необязательный, поскольку существуют архитектуры, в которых целочисленные типы нет имеют такую ​​точную ширину. Только типы leastX и fastX (которые на самом деле могут быть шире, чем указано) являются обязательными.

DevSolar 09.07.2018 18:01

Ошибка в кодовых блоках: error: unknown type name 'uint64_t'; did you mean 'wint_t'?|

john 23.02.2021 16:42

@john: нет, uint64_t. Я считать, что это несколько нестандартное расширение, поэтому разные компиляторы или среды могут иметь разные имена.

Nathan Fellman 23.02.2021 23:15

Это потому, что% 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.

+1 за ссылку на PRIu64, которого я никогда не видел, но он не кажется переносимым на 64-битный Linux (по крайней мере), потому что PRIu64 расширяется до lu вместо llu.

BD at Rivenhill 14.05.2011 02:15

И почему это должно быть плохо? Long - это 64-битное значение в 64-битном Linux, как и во всех других ОС, кроме Windows.

Ringding 04.03.2012 19:06

@BDatRivenhill Linux / Unix использует LP64, в котором long составляет 64 бита

phuclv 16.04.2014 16:51

однако, чтобы сделать его более портативным, используйте вместо него int64_t, потому что вполне могут быть некоторые реализации с long long больше, чем long

phuclv 21.01.2015 07:12

это должно наверх! - одно небольшое обновление: ошибка: неверный суффикс в литерале; C++ 11 требует пробела между литералом и идентификатором [-Wreserved-user-defined-literal]

tofutim 27.08.2018 22:05

В Linux это %llu, а в Windows - %I64u.

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

с Windows (или, по крайней мере, с компилятором Microsoft C для Windows) есть также% I64d,% I32u и% I32d

JustJeff 06.09.2009 18:55

При чем здесь Windows 2000? Библиотека C - это та, которая обрабатывает printf.

CMircea 08.05.2010 22:00

То, что я заметил. Я написал приложение, которое использовало эту конструкцию, и оно отлично работало на WinXP, но выплевывало мусор на Win2k. Может быть, это как-то связано с системным вызовом, который библиотека C делает к ядру, может быть, это как-то связано с Unicode, кто знает. Я помню, что приходилось обходить это с помощью _i64tot () или что-то в этом роде.

Adam Pierce 11.05.2010 10:21

Похоже, MS снова использует свою "свободу инноваций" ... ;-)

Dronz 12.11.2012 10:20

Проблема Win2k / Win9x, вероятно, связана с тем, что тип данных unsigned long long был относительно новым (в то время со стандартом C99), но компиляторы C (включая MinGW / GCC) использовали старую среду выполнения Microsoft C, которая поддерживала только спецификацию C89. У меня есть доступ только к действительно старым и достаточно свежим документам Windows API. Так что сложно сказать, когда именно была прекращена поддержка I64u. Но это похоже на эпоху XP.

veganaiZe 18.06.2018 20:57

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

__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b);    //I is capital i

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

%llu works well.

%d -> для int

%u -> для unsigned int

%ld -> для long int или long

%lu -> для unsigned long int или long unsigned int или unsigned long

%lld -> для long long int или long long

%llu -> для unsigned long long int или unsigned long long

Шестнадцатеричный:

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

Выход:

64bit: FFFFFFFFFFFFFFFF

Очень хорошо! Мне было интересно, как я могу получить его в шестнадцатеричном представлении

0xAK 13.08.2016 01:54

Но почти все компиляторы C++ и C выдают предупреждение: предупреждение: использование модификатора длины 'll' с символом типа 'p' [-Wformat =]

Seshadri R 16.11.2017 12:00
этот совершенно неверный ответ имеет дважды неопределенное поведение и даже не начинает отвечать на вопрос.
Antti Haapala 19.12.2019 00:10

@AnttiHaapala Вы говорите, что этот ответ полностью нарушен двойным неопределенным поведением, вы можете уточнить или мне просто удалить его? Или оставить это как хороший плохой пример?

kungfooman 19.12.2019 12:46

UB1: все указатели имеют одинаковый размер, sizeof (char *) == sizeof (long long *), поэтому модификатор размера для% p бесполезен. UB2: 0xff.fff - это тип int, а формат% p ожидает указатель

brian beuning 17.12.2020 21:26

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

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

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

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

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

Очевидно, никто не придумал мультиплатформенного * решения для более десяти лет с [] 2008 года, поэтому я добавлю свое ?. Пожалуйста, проголосуйте за. (Шучу. Меня это не волнует.)

Решение: lltoa()

Как пользоваться:

#include <stdlib.h> /* lltoa() */
// ...
char dummy[255];
printf("Over 4 bytes: %s\n", lltoa(5555555555, dummy, 10));
printf("Another one: %s\n", lltoa(15555555555, dummy, 10));

Пример ОП:

#include <stdio.h>
#include <stdlib.h> /* lltoa() */

int main() {
    unsigned long long int num = 285212672; // fits in 29 bits
    char dummy[255];
    int normalInt = 5;
    printf("My number is %d bytes wide and its value is %s. "
        "A normal number is %d.\n", 
        sizeof(num), lltoa(num, dummy, 10), normalInt);
    return 0;
}

В отличие от строки формата печати %lld, этот у меня работает под 32-битным GCC в Windows.

*) Что ж, почти мультиплатформенный. В MSVC вам явно нужен _ui64toa() вместо lltoa().

У меня нет lltoa.

Antti Haapala 19.12.2019 00:12

твой смайлик повлиял на мои кимодзи.

Rainning 11.02.2021 05:14

How do you format an unsigned long long int using printf?

Начиная с C99, перед спецификаторами преобразования "ll" используется o,u,x,X (многоточие).

Помимо вариантов с основанием 10 во многих ответах есть варианты с основанием 16 и основанием 8:

Варианты включают

unsigned long long num = 285212672;
printf("Base 10: %llu\n", num);
num += 0xFFF; // For more interesting hex/octal output.
printf("Base 16: %llX\n", num); // Use uppercase A-F
printf("Base 16: %llx\n", num); // Use lowercase a-f
printf("Base  8: %llo\n", num);
puts("or 0x,0X prefix");
printf("Base 16: %#llX %#llX\n", num, 0ull); // When non-zero, print leading 0x
printf("Base 16: %#llx %#llx\n", num, 0ull);
printf("Base 16: 0x%llX\n", num); // My hex fave: lower case prefix, with A-F

Выход

Base 10: 285212672
Base 16: 11000FFF
Base 16: 11000fff
Base  8: 2100007777
or 0x,0X prefix
Base 16: 0X11000FFF 0
Base 16: 0x11000fff 0
Base 16: 0x11000FFF

+ l: "% llu" меня удивил. Я использовал "% ull" и получил предупреждение, что я предоставил int.

Rainning 11.02.2021 05:12

@Rainning "%ull" печатает unsigned, а затем "ll".

chux - Reinstate Monica 11.02.2021 05:44

Другие вопросы по теме