Как отформатировать беззнаковое длинное целое число с помощью printf?
-
08-06-2019 - |
Вопрос
#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
?
Решение
Используйте модификатор ll (el-el) long-long с преобразованием u (беззнаковое).(Работает в Windows, GNU).
printf("%llu", 285212672);
Другие советы
Возможно, вы захотите попробовать использовать библиотеку 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
и т. д., поскольку вам не нужно угадывать, сколько бит в каждом типе данных.
%d
--> для int
%u
--> для unsigned int
%ld
--> для long int
%lu
--> для unsigned long int
%lld
--> для long long int
%llu
--> для unsigned long long int
Для long long (или __int64) с использованием MSVS следует использовать %I64d:
__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b); //I is capital i
Это связано с тем, что %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.
В линуксе это %llu
и в винде это есть %I64u
Хотя я обнаружил, что это не работает в Windows 2000, похоже, там есть ошибка!
Скомпилируйте его как x64 с помощью VS2005:
%llu работает хорошо.
Нестандартные вещи всегда странные :)
за длинную часть под GNU это L
, ll
или q
и под окнами, я думаю, это ll
только
Шестнадцатеричный:
printf("64bit: %llp", 0xffffffffffffffff);
Выход:
64bit: FFFFFFFFFFFFFFFF
В дополнение к тому, что люди писали много лет назад:
- вы можете получить эту ошибку в gcc/mingw:
main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("%llu\n", k);
Тогда ваша версия mingw не имеет значения по умолчанию c99.Добавьте этот флаг компилятора: -std=c99
.
Ну, один из способов — скомпилировать его как 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.
Судя по всему, никто не придумал мультиплатформенного* решения для более десяти лет с 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()
.