我正在尝试打印off_t
和size_t
等类型。 printf()
的便携式的正确占位符是什么?
或者是否有完全不同的方式来打印这些变量?
答案 0 :(得分:102)
您可以将z
用于size_t,将t
用于ptrdiff_t,例如
printf("%zu %zd", size, ptrdiff);
但是我的manpage说一些旧的库使用了与z
不同的字符,并且不鼓励使用它。然而,它是标准化的(按照C99标准)。对于intmax_t
的{{1}}和int8_t
等等,您可以使用宏,就像另一个答案所说的那样:
stdint.h
它们列在printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
的联机帮助页中。
就个人而言,我只会将值转换为inttypes.h
或unsigned long
,就像另一个答案推荐的那样。如果您使用C99,那么您可以(当然应该)投射到long
或unsigned long long
并分别使用long long
或%llu
格式。
答案 1 :(得分:99)
打印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
,这会在其他一些实现上失败,因为它太小了。
答案 2 :(得分:5)
对于微软来说,答案是不同的。 VS2013主要符合C99标准,但“不支持hh,j,z和t长度前缀。”对于size_t “也就是说,32位平台上的无符号__int32,64位平台上的无符号__int64”使用带有类型说明符o,u,x或X的前缀I(大写之眼)。See VS2013 Size specification
对于off_t,它在VC \ include \ sys \ types.h中定义为long。
答案 3 :(得分:3)
您使用的是哪个版本的C?
在C90中,标准做法是根据需要转换为有符号或无符号长,并相应地进行打印。我已经看到%z为size_t,但Harbison和Steele没有在printf()下提及它,并且在任何情况下都无法帮助你使用ptrdiff_t或其他任何东西。
在C99中,各种_t类型都有自己的printf宏,所以像"Size is " FOO " bytes."
这样的东西我不知道细节,但这是一个相当大的数字格式包含文件的一部分。
答案 4 :(得分:3)
您需要使用inttypes.h中的格式化宏。
请参阅此问题:Cross platform format string for variables of type size_t?
答案 5 :(得分:1)
在Linux,OS X和OpenBSD上查看man 3 printf
都显示%z
的{{1}}和size_t
的{{1}}(对于C99),但没有一个提到%t
。在野外提出的建议通常会提供ptrdiff_t
off_t
转换,据我所知,“{1}}和%u
在64之间的变化相同”位和32位系统。)
答案 6 :(得分:1)
如果您使用 C11 或 C18,则可以使用 _Generic
。
#include <stdio.h>
#include <sys/types.h>
#define TYPE_FORMAT(variable) _Generic \
( \
(variable) \
, unsigned char : "%hhu" \
, unsigned short : "%hu" \
, unsigned int : "%u" \
, unsigned long : "%lu" \
, unsigned long long : "%llu" \
, signed char : "%hhi" \
, signed short : "%hi" \
, signed int : "%i" \
, signed long : "%li" \
, signed long long : "%lli" \
)
int main(void)
{
off_t a=3321;
printf(TYPE_FORMAT(a), a);
}
但是,有一个主要缺点:您不能以这种方式组合字符串。意思是:
printf("Foo: " TYPE_FORMAT(a), a);
将不起作用,这使得它在许多情况下毫无用处。是的,您可以在运行时组合字符串,但这很烦人。
答案 7 :(得分:-3)
我至少看过两次这个帖子,因为我接受的答案很难被记住(我很少使用size_t
或size_t
标志而且它们似乎不是platform independant)。
standard从未明确说明if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
的确切数据长度,因此我建议您首先检查平台上的stdint
长度,然后选择其中一个:
cmd.Parameters.Clear
我建议使用For Each part In parts
cmd.Parameters.Clear()
cmd.Parameters.Add(New SqlParameter("@StepId", part))
cmd.Parameters.Add(New SqlParameter("@DateCalculationRule", myRule))
cmd.Parameters.Add(New SqlParameter("@Result", 0))
cmd.Parameters("@Result").Direction = ParameterDirection.Output
Try
cmd.ExecuteNonQuery()
ok = IIf(IsDBNull(cmd.Parameters("@Result").Value), 1, cmd.Parameters("@Result").Value)
RadGrid1.Rebind()
Catch ex As Exception
ok = 1
End Try
Next
类型而不是原始数据类型来构建。
答案 8 :(得分:-4)
我记得,唯一可行的方法是将结果转换为“unsigned long int”并使用%lu
。
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
答案 9 :(得分:-9)
对off_t使用“%zo”。 (八进制) 或“%zu”表示小数。