关于uint32_t和size_t的c:printf格式说明符

printf format specifiers for uint32_t and size_t

我有以下

1
2
3
4
5
size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]
"
, i, k);

编译时收到以下警告:

1
format ‘%lu’ expects type ‘long unsigned int, but argument has type ‘uint32_t

当我使用夹板运行时,得到以下信息:

1
Format argument 1 to printf (%u) expects unsigned int gets size_t: k

非常感谢您的任何建议,


尝试

1
2
3
4
5
#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]
"
, i, k);

z表示长度与size_t相同的整数,并且在C99标头inttypes.h中定义的PRIu32宏表示无符号的32位整数。


听起来像您期望size_tunsigned long(可能是64位)相同,而实际上是unsigned int(32位)。在两种情况下均尝试使用%zu

我还不


所需要的就是格式说明符和类型一致,并且您始终可以强制使其正确。 long至少为32位,因此%lu(unsigned long)k始终正确:

1
2
3
uint32_t k;
printf("%lu
"
, (unsigned long)k);

size_t比较棘手,这就是为什么在C99中添加了%zu的原因。如果不能使用它,则将其像k一样对待(long是C89中最大的类型,size_t不太可能更大)。

1
2
3
4
5
size_t sz;
printf("%zu
"
, sz);  /* C99 version */
printf("%lu
"
, (unsigned long)sz);  /* common C89 version */

如果没有为所传递的类型指定正确的格式说明符,则printf将等同于从数组中读取过多或过少的内存。只要您使用显式强制转换来匹配类型,它都是可移植的。


如果您不想使用PRI *宏,则打印ANY整数类型的另一种方法是强制转换为intmax_tuintmax_t并分别使用"%jd"%ju。这对于未定义PRI *宏的POSIX(或其他OS)类型特别有用,例如off_t