我正在尝试打印类似off_t
和的类型size_t
。printf()
便携式的正确占位符是什么?
还是有一种完全不同的方式来打印这些变量?
我正在尝试打印类似off_t
和的类型size_t
。printf()
便携式的正确占位符是什么?
还是有一种完全不同的方式来打印这些变量?
Answers:
您可以将z
size_t和t
ptrdiff_t用于
printf("%zu %td", size, ptrdiff);
但我的联机帮助页上说,一些较早的库使用的字符不同于,z
并且不鼓励使用它。但是,它是标准化的(通过C99标准)。对于那些intmax_t
和int8_t
的stdint.h
等等,还有你可以使用宏,像另一个回答说:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
它们列在的联机帮助页中inttypes.h
。
就个人而言,我只想投的价值观unsigned long
或long
像另一个答案建议。如果使用C99,则可以(当然应该)强制转换为unsigned long long
or,long long
并分别使用%llu
or %lld
格式。
%zd
具有size_t
是不确定的行为由于符号性失配(C99 7.19.6.1#9)。一定是%zu
。
%zd
有size_t
来自那款或任何其他得到未定义的行为。实际上,%z
#7中的定义显式允许%d
with size_t
和相应的带符号类型,而§6.2.5#9显式允许在期望使用相应的带符号类型的情况下使用无符号类型的值,只要该值是有效的非负值即可。签名类型的。
打印off_t
:
printf("%jd\n", (intmax_t)x);
打印size_t
:
printf("%zu\n", x);
打印ssize_t
:
printf("%zd\n", x);
请参阅C99标准中的7.19.6.1/7,或者更方便的POSIX文档格式代码:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
如果您的实现不支持这些格式代码(例如,因为您使用的是C89),那么由于AFAIK的存在,C89中就不会有整数类型的格式代码,并且一定会保证它的大小。这些类型。因此,您需要做一些特定于实现的事情。
例如,如果您的编译器具有long long
并且标准库支持%lld
,则您可以放心地期望它将代替intmax_t
。但是,如果没有,您将不得不退回到long
,这在其他一些实现上会失败,因为它太小了。
ssize_t
具有相同的大小size_t
,因此真正可移植的代码应该将其转换为intmax_t
并打印,%jd
就像off_t
。
对于Microsoft,答案是不同的。VS2013在很大程度上符合C99,但“不支持hh,j,z和t长度前缀。” 对于size_t“即在32位平台上为无符号__int32,在64位平台上为无符号__int64”,请使用前缀I(大写字母)以及类型说明符o,u,x或X。 请参见VS2013大小规范
至于off_t,它在VC \ include \ sys \ types.h中定义为long。
off_t
始终long
将其设置为32位(即使64位Windows也将32位用于long
)。
您将要使用inttypes.h中的格式化宏。
看到以下问题: 跨平台格式的字符串是否为size_t类型的变量?
off_t
类型大于在支持大文件的任何32位系统上的指针(当前是大多数32位系统)。
在man 3 printf
Linux,OS X和OpenBSD上看,它们都显示了%z
对size_t
和%t
对ptrdiff_t
(对于C99)的支持,但是都没有提及off_t
。在野外的建议通常提供了%u
转换off_t
,这是“正确的足够”据我可以告诉(包括unsigned int
与off_t
64位和32位系统之间的变化相同)。
unsigned int
和64位off_t
。因此,强制转换将导致数据丢失。
我至少看过两次该帖子,因为对于我而言,很难接受已接受的答案(我很少使用z
或j
标志,它们似乎与平台无关)。
该标准从未明确指出的确切数据长度size_t
,因此建议您首先检查size_t
平台的长度,然后选择其中一个:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
而且我建议使用stdint
类型而不是原始数据类型来实现一致性。
%zu
可用于打印size_t
值。绝对不应该使用uint32_t
/ uint64_t
格式说明符来打印size_t
,因为不能保证这些类型是兼容的。
我记得,唯一可移植的方法是将结果转换为“ unsigned long int”并使用%lu
。
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long long
在C ++标准中不存在,因此本质上是不可移植的。
fopen
,我发现该类型用于偏移量。fseek
off_t