C语言中平台无关的size_t格式说明符是什么?

106

我想在C语言中打印一个size_t类型的变量,但是在不同的架构上size_t被别名为不同的变量类型。例如,在一台机器上(64位),以下代码不会产生任何警告:

size_t size = 1;
printf("the size is %ld", size);

但在我的另一台机器上(32位),以上代码会产生以下警告信息:

警告:格式“%ld”期望类型为“long int *”,但参数3的类型为“size_t *”

我怀疑这是由于指针大小的差异导致的,在我的64位机器上,size_t被别名为long int"%ld"),而在我的32位机器上,size_t被别名为另一种类型。

有没有特定于size_t的格式说明符?


1
你的警告信息与代码不匹配。警告提到了指针,但你的代码中并没有任何指针。你是否在某个地方删除了一些 & 符号? - Jens
指针?不,我没有收到任何有关指针的警告,事实上,根据我运行代码的机器不同,有时候我根本就没有收到任何警告。请尝试以下测试代码:#include int main(){ size_t size = 1; printf("the size is %ld", size); return 0; } - Ethan Heilman
1
@EthanHeilman他指的是您的警告说warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *',但它可能应该是说warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'。你是不是在使用scanf()时得到这些警告? - RastaJedi
1
可能是如何正确使用printf打印size_t?的重复问题。 - phuclv
3个回答

143

是的:使用z长度修饰符:

size_t size = sizeof(char);
printf("the size is %zu\n", size);  // decimal size_t ("u" for unsigned)
printf("the size is %zx\n", size);  // hex size_t

其他可用的长度修饰符包括hh(用于char类型),h(用于short类型),l(用于long类型),ll(用于long long类型),j(用于intmax_t类型),t(用于ptrdiff_t类型)和L(用于long double类型)。详见C99标准§7.19.6.1(7)部分。

zd和zu有什么区别?我知道zd是十进制,但它是否带符号,如果是的话,zd带符号会对事情产生什么影响。 - Ethan Heilman
1
иҝҷжҳҜsize_tе’Ңssize_tд№Ӣй—ҙзҡ„еҢәеҲ«пјӣеҗҺиҖ…еҫҲе°‘дҪҝз”ЁгҖӮ - Adam Rosenfield
26
在这种情况下,你应该使用 %zu,因为参数是无符号的。 - caf
其他可用选项在printf手册页面中有解释:http://linux.die.net/man/3/printf - INS
这也是 C89/90 的一部分吗? - detly
10
@detly:不,z长度修饰符不是C89/C90的一部分。如果你的目标是编写符合C89标准的代码,那么你最好将其转换为unsigned long并使用l长度修饰符,例如printf("the size is %lu\n", (unsigned long)size);;支持C89和具有比long更大的size_t的系统更加棘手,需要使用许多预处理器宏。 - Adam Rosenfield

52

有的,它是 %zu(正如 ANSI C99 中规定的那样)。

size_t size = 1;
printf("the size is %zu", size);
注意,size_t是无符号整数,因此%ld是错误的:错误的长度修饰符和错误的格式转换说明符。如果您想知道,%zd用于ssize_t(它是有符号的)。

请注意,size_t是无符号整数,因此%ld是完全错误的:使用了错误的长度修饰符和格式转换说明符。如果您感到困惑,%zd是用于表示带符号值的ssize_t


1

MSDN指出,Visual Studio支持在32位和64位平台上可移植的代码中使用"I"前缀。

size_t size = 10;
printf("size is %Iu", size);

7
这是一种MS特有的功能,不符合标准规范,因此不能在各个平台通用。 - phuclv
1
@phuclv确实如此。如果答案所示确实说“便携式”,那么这比我对微软的了解还要糟糕。虽然这并不会让我感到惊讶……我不会因为有人尝试回答问题而投反对票,但是这个答案仍然是错误的。啊,我想我明白了“便携式”的想法。它必须是在说它适用于32位和64位。但当然它会适用。 - Pryftan

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