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

275
#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() a unsigned long long int?

  • 1
    Я только что скомпилировал ваш код (с% llu) с помощью gcc, и вывод был правильным. Вы передаете какие-либо параметры компилятору?
  • 1
    Обратите внимание, что newlib samsung bada, похоже, не поддерживает "% lld": developer.bada.com/forum/…
Показать ещё 2 комментария
Теги:
syntax
printf
format-specifiers
long-long

11 ответов

361
Лучший ответ

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

printf("%llu", 285212672);
  • 18
    Не работает в Windows - это только для Linux / UNIX.
  • 6
    Или, если быть точным, это для GNU libc, и не работает с Microsoft C времени выполнения.
Показать ещё 11 комментариев
67

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

  • 0
    где эти PRId64 , PRId32 определены?
  • 3
    @happy_marmoset: они определены в inttypes.h
Показать ещё 4 комментария
30

В течение долгого времени (или __int64) с использованием MSVS вы должны использовать% I64d:

__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b);    //I is capital i
  • 0
    Это также работает:% I64x
27

Это потому, что% 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.
  • 0
    +1 за ссылку на PRIu64, которую я никогда не видел, но она не выглядит переносимой для 64-битного Linux (по крайней мере), потому что PRIu64 расширяется до «lu» вместо «llu».
  • 7
    И почему это было бы плохо? Long - это 64-битное значение в 64-битной Linux, как и в любой другой ОС, кроме Windows.
Показать ещё 3 комментария
23

%d → для int

%ld → для long int

%lld → для long long int

%llu → для unsigned long long int

  • 0
    Я должен запомнить эти вещи ...
8

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

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

8

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

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

  • 0
    с Windows (или, по крайней мере, с компилятором Microsoft C для Windows) также есть% I64d,% I32u и% I32d
  • 1
    Какое это имеет отношение к Windows 2000? Библиотека C - это та, которая обрабатывает printf.
Показать ещё 3 комментария
4

Hex:

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

Вывод:

64bit: FFFFFFFFFFFFFFFF
  • 0
    Очень хорошо! мне было интересно, как я мог получить его в шестнадцатеричном представлении
  • 0
    Но почти все компиляторы C ++ и C выдают предупреждение: warning: использовать модификатор длины 'll' с символом типа 'p' [-Wformat =]
4

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

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

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

2

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

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

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

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

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

1

Ну, один из способов заключается в том, чтобы скомпилировать его как 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
    Попробуйте использовать действительное 64-разрядное число вместо «285212672», и я не верю, что первый пример работает правильно, скомпилированный для любой цели.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню