提问人:ant2009 提问时间:7/3/2010 最后编辑:jwwant2009 更新时间:11/3/2021 访问量:317573
用于uint32_t和size_t的 printf 格式说明符
printf format specifiers for uint32_t and size_t
问:
我有以下几点
size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]\n", i, k);
编译时收到以下警告:
format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’
当我使用夹板运行它时,我得到了以下内容:
Format argument 1 to printf (%u) expects unsigned int gets size_t: k
非常感谢您的任何建议,
答:
40赞
Cogwheel
7/3/2010
#1
听起来你期望与(可能是 64 位)相同,而它实际上是(32 位)。在这两种情况下都尝试使用。size_t
unsigned long
unsigned int
%zu
不过我不完全确定。
评论
1赞
ant2009
7/3/2010
编译时没有警告。但是,运行夹板我得到以下结果: 1) printf (%u) 期望无符号 int 得到 uint32_t: i 2) printf (%u) 期望无符号 int 得到 size_t: k
0赞
Cogwheel
7/3/2010
听起来夹板只是迂腐。它可能偏离了源代码中的类型名称,并且没有意识到它们是等效的。我想知道它会对@KennyTM的答案有什么影响......它当然应该更便携。
3赞
R.. GitHub STOP HELPING ICE
7/4/2010
夹板实际上是在做正确的事情。仅仅因为碰巧在您的编译器/平台上并不意味着它可能不在另一个编译器/平台上。与 .它实际上正在竭尽全力并做更多的工作来检测这个可移植性错误,因为简单、自然的检查就是像编译器一样尊重 typedef。int32_t
int
long
size_t
5赞
u0b34a0f6ae
11/9/2011
-1,对不起,它不是便携式的。所需要的只是格式说明符和类型一致,并且您始终可以强制转换以使其为真。long 至少为 32 位,因此 with 始终正确。 更棘手,这就是在 C99 中添加的原因。如果你不能使用它,那么就把它当作(是 C89 中最大的类型,不太可能更大)。%lu
(unsigned long)k
size_t
%zu
k
long
size_t
162赞
kennytm
7/3/2010
#2
尝试
#include <inttypes.h>
...
printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);
表示长度与 相同的整数,在 C99 标头 inttypes.h
中定义的宏表示无符号的 32 位整数。z
size_t
PRIu32
评论
4赞
kennytm
7/3/2010
@robUK:呵呵。我建议你为夹板提交一个错误。
11赞
Dummy00001
7/3/2010
这是正确的答案。虽然我个人的建议是简单地投射,例如.否则,由于类型更改,以后会在整个代码中出现一堆警告。printf( "%lu", (unsigned long )i )
1赞
R.. GitHub STOP HELPING ICE
7/3/2010
这是正确的答案。我同意 KennyTM 关于为夹板提交错误的观点。顺便说一句,“%zu”是size_t的正确格式。您不需要任何 PRI* 宏来打印size_t。
1赞
alcor
10/15/2013
如果我没记错的话,%zu 是 C99,在问题中他写了“C89”。
9赞
Colin D Bennett
10/25/2013
@alcor是的,他确实放置了 C89(显然是他正在使用的 gcc 编译器标志),但他正在使用,所以实际上它是 C99 代码,应该这样编译。uint32_t
20赞
R.. GitHub STOP HELPING ICE
7/3/2010
#3
如果您不想使用 PRI* 宏,打印任何整数类型的另一种方法是分别转换为 或 和 使用 或。这对于未定义 PRI* 宏的 POSIX(或其他操作系统)类型特别有用,例如。intmax_t
uintmax_t
"%jd"
%ju
off_t
33赞
u0b34a0f6ae
11/9/2011
#4
所需要的只是格式说明符和类型一致,并且您始终可以强制转换以使其为真。 至少为 32 位,因此与一起始终正确:long
%lu
(unsigned long)k
uint32_t k;
printf("%lu\n", (unsigned long)k);
size_t
更棘手,这就是在 C99 中添加的原因。如果你不能使用它,那么就把它当作(是 C89 中最大的类型,不太可能更大)。%zu
k
long
size_t
size_t sz;
printf("%zu\n", sz); /* C99 version */
printf("%lu\n", (unsigned long)sz); /* common C89 version */
如果不能为所传递的类型正确设置格式说明符,则相当于从数组中读取过多或过少的内存。只要使用显式强制转换来匹配类型,它就是可移植的。printf
评论
uint32_t
<stdint.h>
<inttypes.h>
size_t
"%zu"
uint32_t
size_t