printf是否需要使用%zu格式说明符?

17
我们在一个嵌入式平台上使用C89。我试图打印出size_t,但它没有起作用:

我们在嵌入式平台上使用C89。我尝试打印一个size_t,但无法运行:

#include <stdio.h>
int main(void) {
    size_t n = 123;
    printf("%zu\n",n);
    return 0;
}

我得到了zu而不是123
其他说明符工作正常。

如果存在size_t,为什么printf中也没有zu可用?
这是我应该联系图书馆供应商的问题,还是库实现允许将其排除在外?


5
我认为在 C99 中加入了 z 前缀。 - Kerrek SB
一个C++的引用为什么要涉及到C标准呢? - mch
这是一篇关于 C++ 历史的文章:http://www.cplusplus.com/articles/iz3hAqkS/ - LPs
1
现在已经标记在cppreference上。 - Cubbi
@mch 对,我本来想发布C参考资料的。 - Trevor Hickey
显示剩余2条评论
3个回答

26
如果size_t存在,printf中也应该有zu才对吧?
至少从C89开始就已经存在了size_t,但相应的格式说明符%zu(特别是长度修饰符z)仅自C99标准以来才被添加进去。
因此,如果你不能使用C99(或C11),并且必须在C89中打印size_t,那么你只需回退到其他现有类型,例如:
printf("%lu\n", (unsigned long)n);

1
请注意,上述代码在任何平台上都足够,尽管不一定高效,只要unsigned long足够大以容纳最大可能的n值(无论它是否足够处理完整的size_t范围)。然而,并不能保证size_t不会比unsigned long更大,也可能没有任何保证n始终适合于unsigned long。我不知道这会成为多大的问题[如果计算sprintf缓冲区的大小,许多程序可能会遇到不同的麻烦...] - supercat
基于一种假设,即十进制格式的无符号长整型的最大长度为10位数字,并且要输出的值超过了这个长度。 - supercat
1
为了更好的可移植性,请使用 printf("%llu\n", (unsigned long long)n);,除非您知道大小很小,例如 sizeof(int),在这种情况下,您可以简单地编写 printf("%u\n", (unsigned)n); - chqrlie
3
在C89标准中没有unsigned long long这种类型,所以我建议使用unsigned long。如果可用unsigned long long(C99),那么可以使用%zu作为size_t的占位符。因此,在此处根本不需要强制转换为unsigned long long - P.P

-5

size_t 是由 sizeof() 函数返回的。%zu 标识符用于打印长度。因此,要返回 n 的大小,代码应该如下所示:#include <stdio.h>

int main(void) { size_t n=123; printf("%zu\n",sizeof (n)); return 0;` }


-9

这个工作正常。在我的系统中,它正在打印预期值。 您可能由于编译器而出现错误。我正在使用GCC编译器。如果您只有这个,并尝试获取输出,请先更新GCC,然后再尝试。它会起作用。

Your program input

The output of the program


2
问题实际上位于C库中。一个常见的情况是,在使用gcc与系统的Microsoft C库组合的旧版本MinGW中,不支持%zu,直到最近才开始支持大多数C99扩展。 - chqrlie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接