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

Ответов (13)

Решение

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

printf("%llu", 285212672);

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

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

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

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

%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

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

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

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

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

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

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

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

Выход:

64bit: FFFFFFFFFFFFFFFF

Как вы форматируете unsigned long long intиспользование 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

Очевидно, никто не придумал многоплатформенного * решения более десяти лет с [] 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));

Пример OP:

#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().

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

для длинной длинной части под 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.

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

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

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

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