我应该如何打印像off_t和size_t这样的类型?

发布于 2024-07-14 08:07:20 字数 118 浏览 7 评论 0原文

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

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

I'm trying to print types like off_t and size_t. What is the correct placeholder for printf() that is portable?

Or is there a completely different way to print those variables?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

站稳脚跟 2024-07-21 08:07:20

打印 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< /a>

如果您的实现不支持这些格式化代码(例如因为您使用的是 C89),那么您就会遇到一些问题,因为据我所知,C89 中没有整数类型具有格式化代码并且保证与这些类型一样大。 所以你需要做一些特定于实现的事情。

例如,如果您的编译器有 long long 并且您的标准库支持 %lld,您可以放心地期望它将代替 intmax_t。 但如果没有,您将不得不退回到 long,这在其他一些实现上会失败,因为它太小了。

To print off_t:

printf("%jd\n", (intmax_t)x);

To print size_t:

printf("%zu\n", x);

To print ssize_t:

printf("%zd\n", x);

See 7.19.6.1/7 in the C99 standard, or the more convenient POSIX documentation of formatting codes:

http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html

If your implementation doesn't support those formatting codes (for example because you're on C89), then you have a bit of a problem since AFAIK there aren't integer types in C89 that have formatting codes and are guaranteed to be as big as these types. So you need to do something implementation-specific.

For example if your compiler has long long and your standard library supports %lld, you can confidently expect that will serve in place of intmax_t. But if it doesn't, you'll have to fall back to long, which would fail on some other implementations because it's too small.

一枫情书 2024-07-21 08:07:20

您可以使用 z 表示 size_t,使用 t 表示 ptrdiff_t,例如

printf("%zu %td", size, ptrdiff);

但我的联机帮助页说一些较旧的库使用了与 z 不同的字符,并且不鼓励使用它。 尽管如此,它还是标准化的(根据 C99 标准)。 对于 stdint.h 的那些 intmax_tint8_t 等,您可以使用宏,就像另一个答案所说:

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

它们列在inttypes.h 的联机帮助页。

就我个人而言,我只会像另一个答案建议的那样将值转换为 unsigned longlong 。 如果您使用 C99,那么您可以(当然应该)转换为 unsigned long longlong long 并使用 %llu%lld 分别为格式。

You can use z for size_t and t for ptrdiff_t like in

printf("%zu %td", size, ptrdiff);

But my manpage says some older library used a different character than z and discourages use of it. Nevertheless, it's standardized (by the C99 standard). For those intmax_t and int8_t of stdint.h and so on, there are macros you can use, like another answer said:

printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);

They are listed in the manpage of inttypes.h.

Personally, I would just cast the values to unsigned long or long like another answer recommends. If you use C99, then you can (and should, of course) cast to unsigned long long or long long and use the %llu or %lld formats respectively.

段念尘 2024-07-21 08:07:20

对于微软来说,答案是不同的。 VS2013 很大程度上符合 C99,但“不支持 hh、j、z 和 t 长度前缀。” 对于尺寸_t
“即,32 位平台上的 unsigned __int32,64 位平台上的 unsigned __int64”使用前缀 I(大写字母)和类型说明符 o、u、x 或 X。 microsoft.com/en-us/library/tcxf1dw6.aspx" rel="noreferrer">参见VS2013大小规范

至于off_t,在VC\include\sys\types.h中定义为long。

For Microsoft, the answer is different. VS2013 is largely C99 compliant but "[t]he hh, j, z, and t length prefixes are not supported." For size_t
"that is, unsigned __int32 on 32-bit platforms, unsigned __int64 on 64-bit platforms" use prefix I (capital eye) with type specifier o, u, x, or X. See VS2013 Size specification

As for off_t, it is defined as long in VC\include\sys\types.h.

虫児飞 2024-07-21 08:07:20

您将需要使用 inttypes.h 中的格式化宏。

请参阅此问题: size_t 类型变量的跨平台格式字符串?

You'll want to use the formatting macros from inttypes.h.

See this question: Cross platform format string for variables of type size_t?

°如果伤别离去 2024-07-21 08:07:20

您使用的是哪个版本的 C?

在 C90 中,标准做法是根据需要转换为有符号或无符号长整型,并相应地进行打印。 我见过 size_t 的 %z ,但是 Harbison 和 Steele 没有在 printf() 下提到它,无论如何这对你处理 ptrdiff_t 或其他什么都没有帮助。

在 C99 中,各种 _t 类型都带有自己的 printf 宏,因此类似 “大小为“ FOO ”字节。” 我不知道详细信息,但这是相当大的数字格式的一部分,包括文件。

Which version of C are you using?

In C90, the standard practice is to cast to signed or unsigned long, as appropriate, and print accordingly. I've seen %z for size_t, but Harbison and Steele don't mention it under printf(), and in any case that wouldn't help you with ptrdiff_t or whatever.

In C99, the various _t types come with their own printf macros, so something like "Size is " FOO " bytes." I don't know details, but that's part of a fairly large numeric format include file.

我家小可爱 2024-07-21 08:07:20

查看 Linux、OS X 和 OpenBSD 上的 man 3 printf 都显示对 size_t%t%z 的支持code> 为 ptrdiff_t(对于 C99),但这些都没有提到 off_t。 野外建议通常会为 off_t 提供 %u 转换,据我所知,这是“足够正确的”(都是 unsigned intoff_t 在 64 位和 32 位系统之间变化相同)。

Looking at man 3 printf on Linux, OS X, and OpenBSD all show support for %z for size_t and %t for ptrdiff_t (for C99), but none of those mention off_t. Suggestions in the wild usually offer up the %u conversion for off_t, which is "correct enough" as far as I can tell (both unsigned int and off_t vary identically between 64-bit and 32-bit systems).

只想待在家 2024-07-21 08:07:20

如果您使用 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);

不起作用,这使得它在许多情况下毫无用处。 是的,您可以在运行时组合字符串,但这很烦人。

If you use C11 or C18, you can use _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);
  }
      

However, there is one major drawback: You can not combine strings this way. Means this:

printf("Foo: " TYPE_FORMAT(a), a);

will not work, which makes it useless for many situation. Yes you could combine the string during runtime but that is annoying.

吻泪 2024-07-21 08:07:20

我至少看到这篇文章两次,因为接受的答案对我来说很难记住(我很少使用 zj 标志,它们似乎不是 平台无关)。

标准从未明确说明size_t的确切数据长度,因此我建议您首先检查您平台上的长度 size_t 然后选择其中之一:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

我建议使用 stdint 类型而不是原始数据类型以保持一致性。

I saw this post at least twice, because the accepted answer is hard to remeber for me(I rarely use z or j flags and they are seems not platform independant).

The standard never says clearly the exact data length of size_t, so I suggest you should first check the length size_t on your platform then select one of them:

if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64

And I suggest using stdint types instead of raw data types for consistancy.

怪异←思 2024-07-21 08:07:20

我记得,唯一可移植的方法是将结果转换为“unsigned long int”并使用 %lu

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));

As I recall, the only portable way to do it, is to cast the result to "unsigned long int" and use %lu.

printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
也只是曾经 2024-07-21 08:07:20

使用“%zo”作为 off_t。 (八进制)
或“%zu”表示十进制。

use "%zo" for off_t. (octal)
or "%zu" for decimal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文