#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);
%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
您可能想尝试使用为您提供 int32_t
、int64_t
、uint64_t
等类型的 inttypes.h 库。然后您可以使用它的宏,例如:
uint64_t x;
uint32_t y;
printf("x: %"PRId64", y: %"PRId32"\n", x, y);
这是“保证”不会给您带来与 long
、unsigned long long
等相同的麻烦,因为您不必猜测每种数据类型中有多少位。
PRId64
、PRId32
宏定义在哪里?
inttypes.h
中定义
PRIu64
和 PRIu32
来表示无符号整数。
inttypes.h
是标准的吗?不是stdint.h
吗?
leastX
和 fastX
类型(实际上可能比指定的更宽)是强制性的。
对于使用 MSVS 的 long long(或 __int64),您应该使用 %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.
int64_t
,因为很可能有一些实现 long long 大于 long
"%" PRIu64
匹配 uint64_t
,"%llu"
匹配 unsigned long long
。这个答案有 "%" PRIu64
和 unsigned long long
。当 unsigned long long
大于 64 位时,此方法为 UB 播种。最好避免。
在 Linux 中为 %llu
,在 Windows 中为 %I64u
虽然我发现它在 Windows 2000 中不起作用,但那里似乎有一个错误!
unsigned long long
数据类型相对较新(当时使用 C99 标准),但 C 编译器(包括 MinGW/GCC)使用仅支持 C89 规范的旧 Microsoft C 运行时。我只能访问真正古老且相当新的 Windows API 文档。所以很难准确地说出 I64u
支持是什么时候加入的。但这听起来像是 XP 时代。
使用 VS2005 将其编译为 x64:
%llu 运行良好。
显然,自 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
打印格式字符串不同,这个字符串适用于我在 Windows 上的 32 位 GCC 下。
*) 嗯,几乎是多平台的。在 MSVC 中,您显然需要 _ui64toa()
而不是 lltoa()
。
lltoa
。
lltoa()
不是标准 C 库函数。除非允许非标准扩展,否则编译时它在 Windows 上的 32 位 GCC 下不起作用。
sizeof(num)
返回一个 size_t
。 "%d"
未指定使用它。 "%zu"
更好。
如何使用 printf 格式化 unsigned long long int?
由于 C99 在转换说明符 o,u,x,X
之前使用 "ll"
(ell-ell)。
除了许多答案中的 base 10 选项外,还有 base 16 和 base 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); // When non-zero, print leading 0x
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
int
。
"%ull"
打印一个 unsigned
,然后是 "ll"
。
除了人们多年前写的:
您可能会在 gcc/mingw 上收到此错误:
main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("%llu\n", k);
那么你的mingw版本不默认为c99。添加此编译器标志:-std=c99
。
非标准的东西总是很奇怪:)
对于 GNU 下的 long long 部分,它是 L
、ll
或 q
在 Windows 下我相信它只是 ll
好吧,一种方法是使用 VS2008 将其编译为 x64
这将按您的预期运行:
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 编译器。
十六进制:
printf("64bit: %llp", 0xffffffffffffffff);
输出:
64bit: FFFFFFFFFFFFFFFF
long long
参数传递给printf
并为其中一个使用错误格式,例如使用%d
而不是%lld
,那么即使是打印的参数在不正确的参数之后也可能完全关闭(甚至可能导致printf
崩溃)。本质上,变量参数是在没有任何类型信息的情况下传递给 printf 的,因此如果格式字符串不正确,则结果是不可预测的。