使用printf正确打印size_t的方法是什么?

86

size_t被定义为无符号整数,但它的大小取决于您使用的是32位或64位计算机。正确且可移植的打印size_t的方法是什么?


4
可能是与如何跨平台格式化size_t类型变量的字符串?重复。 - Ciro Santilli OurBigBook.com
@black 你也可以提议关闭另一种方式。对我来说两种方式都可以。 - Ciro Santilli OurBigBook.com
3个回答

126

4
size_t是一种无符号类型,因此在格式化时仍需要使用'u'作为格式类型以及'z'长度修饰符。 - CB Bailey
9
另外,'z'修饰符是printf的C99补充,因此它并不严格属于标准C++功能。 - CB Bailey
3
我的编译器(gcc)给出警告:unknown conversion type character 'z' in format [-Wformat]|,当程序运行时,它只打印zu作为输出。 - lost_in_the_source
@JaredPar 如果您在编译时选择了人类语言输出,那么std::cout才能使用。不同语言的语法强制您在想要使用不同语言时采用参数。嗯,您可以使用boost来获得类型安全的printf功能,但这也不是严格的C++。 - Keinstein
2
@Ruslan,因此引入了位置参数。请参见https://dev59.com/kG015IYBdhLWcg3w6QA0。如果使用它们,则您的担忧不适用。 - Keinstein
显示剩余3条评论

10

这个问题与C++有关,因此 cout << 是另一个可能的答案。

在所有版本的C语言中,这个问题都难以解决。在C90中,将类型转换为 unsigned long 可能有效,但在C99中可能无效,而C99解决方案在C90中也不一定有效。可靠地区分C90和C99的能力是在1995年的更改中引入的(规定了__STDC__ 的允许值)。我认为没有完全可移植的方式适用于C90、C99和C++,尽管在这些语言中的任何一个都有解决方案。


9
我认为C++的答案是:
std::size_t n = 1;
std::cout << n;

对于C风格的IO,情况稍微复杂一些。在C99中,他们添加了用于size_t值的z长度修饰符。然而,在TR1之前,这个修饰符是不被支持的,所以你只能将其转换为特定的大小,如下所示:
std::size_t n = 1;
std::printf("%lu\n", static_cast<unsigned long>(n));

再次说明,unsigned long long 在C++中并没有得到完全支持,所以以上代码可以正常工作,因为unsigned long是最大的合法整数类型。在TR1之后,您可以安全地使用%zu来表示size_t值。


C++为什么不支持unsigned long long?如果你是基于某些平台上sizeof大小相同的话来判断,那不等同于它不被支持。请注意,我对C++非常反感(即使我觉得它很丑陋),但我从未遇到过不支持unsigned long long的C++编译器。当然,它肯定支持uint64_t。 - Pryftan

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