如何使用printf格式化unsigned long long int?


379
#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


2
我刚刚用gcc编译了您的代码(使用%llu),输出是正确的代码。您是否将任何选项传递给编译器?
胡安

2
需要注意的是三星bada的newlib好像不支持“%LLD”:developer.bada.com/forum/...
RZR


我建议使用stdint.h并明确说明变量中的位数。我们仍处于32位和64位体系结构之间的过渡时期,“ unsigned long long int”在两者上并不意味着同一件事。
2011年

Answers:


483

将ll(el-el)long-long修饰符与u(无符号)转换一起使用。(在Windows,GNU中运行)。

printf("%llu", 285212672);

11
确切地说,它是针对GNU libc的,不适用于Microsoft的C运行时。
Mark Ba​​ker

168
这不是Linux / UNIX,而是在C99的Standard C中添加了“ ll”长度修饰符,如果它在“ Microsoft C”中不起作用,那是因为它们不符合标准。
罗伯特·格兰伯

12
在VS2008中为我工作。而且,据我所知,MS C编译器(设置为直接编译C时)在设计上应该符合C90。C99引入了一些并非所有人都喜欢的东西。
スーパーファミコン

6
这里要记住的一件事是,如果您long long要向其中传递多个参数printf并使用错误的格式(例如%d而不是)%lld,则即使在错误的参数之后打印的参数也可能会完全关闭(甚至可能导致printf崩溃) )。本质上,变量参数不带任何类型信息而传递给printf,因此,如果格式字符串不正确,则结果是不可预测的。
dmitrii 2012年

1
Heard Herb Sutter在一次采访中说,微软的客户不要求C99,因此他们的纯C编译器已冻结在C90。如果您使用C进行编译,则适用。如果像上面其他人所指出的那样,使用C ++进行编译,则应该可以。
ahcox 2012年

90

您可能需要使用inttypes.h库,让你的类型,如尝试 int32_tint64_tuint64_t等等,那么你可以使用它的宏,例如:

uint64_t x;
uint32_t y;

printf("x: %"PRId64", y: %"PRId32"\n", x, y);

这是“保证”不给你同样的麻烦的longunsigned long long等等,因为你不必去猜测有多少位是每个数据类型。


这些地方PRId64PRId32宏定义?
happy_marmoset

4
@happy_marmoset:它们的定义是inttypes.h
Nathan Fellman

4
我认为你需要PRIu64,并PRIu32为无符号整数。
Lasse Kliemann

1
inttypes.h标准的吗?不是stdint.h吗?
MD XF

2
请注意,这些精确宽度类型是可选的,因为有些架构没有这些精确宽度的整数类型。只有leastXfastX类型(实际上可能比指示的宽)是强制性的。
DevSolar '18

78

%d->为 int

%u->为 unsigned int

%ld-> long intlong

%lu- >为unsigned long intlong unsigned intunsigned long

%lld-> long long intlong long

%llu-> unsigned long long intunsigned long long


是否有格式说明符,例如要显示的位数,%lld或%llu的左对齐或右对齐?
阿萨姆·帕德(

40

对于使用MSVS的很长一段时间(或__int64),应该使用%I64d:

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

37

这是因为%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在里文希尔(Rivenhill)

8
为什么那会不好?long是64位Linux上的64位值,与Windows之外的其他所有OS一样。
2012年

@BDatRivenhill Linux / Unix使用LP64,其中long是64位
phuclv 2014年

1
但是,要使其更具可移植性,请int64_t改用,因为有些实现的长度可能长于长而长
phuclv 2015年

这应该到顶部!-一个小的更新:错误:字面量后缀无效;C ++ 11在文字和标识符[-Wreserved-user-defined-literal]之间需要一个空格
tofutim,

14

在Linux中是%llu,在Windows中是%I64u

尽管我发现它在Windows 2000中不起作用,但那里似乎有一个错误!


使用Windows,(或至少使用Windows的Microsoft C编译器)还有%I64d,%I32u和%I32d
JustJeff

1
它与Windows 2000有什么关系?C库是处理printf的库。
CMircea

1
就是我观察到的。我编写了一个使用此构造的应用程序,该应用程序在WinXP上运行良好,但在Win2k上出现了垃圾。也许这与C库对内核进行的系统调用有关,也许与Unicode有关,谁知道。我记得必须使用_i64tot()或类似方法来解决它。
亚当·皮尔斯

7
听起来就像MS再次行使其“自由创新” ... ;-)
德隆兹(Dronz)2012年

Win2k / Win9x问题可能是由于unsigned long long数据类型相对较新(当时为C99标准),但C编译器(包括MinGW / GCC)使用的是仅支持C89规范的旧Microsoft C运行时。我只能访问真正古老且相当新的Windows API文档。因此,很难确切地说出何时I64u取消支持。但这听起来像XP时代。
veganaiZe

8

使用VS2005将其编译为x64:

%llu运作良好。


3

除了人们几年前写的东西:

  • 您可能会在gcc / mingw上收到此错误:

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

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

然后,您的mingw版本不会默认为c99。添加此编译器标志:-std=c99


3

显然,自2008年以来,十多年来没有人提出过多平台*解决方案,因此我将附上我的mine。请投票。(开玩笑。我不在乎。)

解: 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()


1
我没有lltoa
Antti Haapala

1

非标准的东西总是很奇怪:)

在GNU下的很长的部分是Lll或者q

在Windows下,我相信这ll只是


1

十六进制:

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

输出:

64bit: FFFFFFFFFFFFFFFF

非常好!我想知道如何以十六进制表示形式获取它
0xAK

但是,几乎所有的C ++和C编译器都发出警告:警告:使用带有'p'类型字符[-Wformat =]的'll'长度修饰符
Seshadri R

2
这个完全破裂的答案具有双重不确定的行为,甚至没有开始回答问题
安蒂·哈帕拉

@AnttiHaapala您说这个答案完全是双重不确定的行为,您能否阐述一下,还是我应该删除它?还是保留它作为一个很好的坏例子?
lama12345

0

好吧,一种方法是使用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编译器。


尝试使用实际的64位数字而不是'285212672',我不认为第一个示例可以正确运行并编译为任何目标。
dyasta
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.