我该如何打印off_t和size_t等类型?

时间:2009-02-25 17:11:47

标签: c portability format-specifiers

我正在尝试打印off_tsize_t等类型。 printf() 的便携式的正确占位符是什么?

或者是否有完全不同的方式来打印这些变量?

10 个答案:

答案 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.hunsigned long,就像另一个答案推荐的那样。如果您使用C99,那么您可以(当然应该)投射到longunsigned 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_tsize_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”表示小数。