我应该如何打印像off_t和size_t这样的类型?
我正在尝试打印 off_t
和 size_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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
打印
off_t
:打印
size_t
:打印
ssize_t
:请参阅 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
:To print
size_t
:To print
ssize_t
: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 ofintmax_t
. But if it doesn't, you'll have to fall back tolong
, which would fail on some other implementations because it's too small.您可以使用
z
表示 size_t,使用t
表示 ptrdiff_t,例如但我的联机帮助页说一些较旧的库使用了与
z
不同的字符,并且不鼓励使用它。 尽管如此,它还是标准化的(根据 C99 标准)。 对于stdint.h
的那些intmax_t
和int8_t
等,您可以使用宏,就像另一个答案所说:它们列在
inttypes.h
的联机帮助页。就我个人而言,我只会像另一个答案建议的那样将值转换为
unsigned long
或long
。 如果您使用 C99,那么您可以(当然应该)转换为unsigned long long
或long long
并使用%llu
或%lld
分别为格式。You can use
z
for size_t andt
for ptrdiff_t like inBut 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 thoseintmax_t
andint8_t
ofstdint.h
and so on, there are macros you can use, like another answer said:They are listed in the manpage of
inttypes.h
.Personally, I would just cast the values to
unsigned long
orlong
like another answer recommends. If you use C99, then you can (and should, of course) cast tounsigned long long
orlong long
and use the%llu
or%lld
formats respectively.对于微软来说,答案是不同的。 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.
您将需要使用 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?
您使用的是哪个版本的 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.查看 Linux、OS X 和 OpenBSD 上的
man 3 printf
都显示对size_t
和%t
%z 的支持code> 为ptrdiff_t
(对于 C99),但这些都没有提到off_t
。 野外建议通常会为off_t
提供%u
转换,据我所知,这是“足够正确的”(都是unsigned int
和off_t
在 64 位和 32 位系统之间变化相同)。Looking at
man 3 printf
on Linux, OS X, and OpenBSD all show support for%z
forsize_t
and%t
forptrdiff_t
(for C99), but none of those mentionoff_t
. Suggestions in the wild usually offer up the%u
conversion foroff_t
, which is "correct enough" as far as I can tell (bothunsigned int
andoff_t
vary identically between 64-bit and 32-bit systems).如果您使用 C11 或 C18,则可以使用
_Generic
。但是,有一个主要缺点:不能以这种方式组合字符串。 意味着:
printf("Foo: " TYPE_FORMAT(a), a);
不起作用,这使得它在许多情况下毫无用处。 是的,您可以在运行时组合字符串,但这很烦人。
If you use C11 or C18, you can use
_Generic
.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.
我至少看到这篇文章两次,因为接受的答案对我来说很难记住(我很少使用
z
或j
标志,它们似乎不是 平台无关)。标准从未明确说明
size_t
的确切数据长度,因此我建议您首先检查您平台上的长度size_t
然后选择其中之一:我建议使用
stdint
类型而不是原始数据类型以保持一致性。I saw this post at least twice, because the accepted answer is hard to remeber for me(I rarely use
z
orj
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 lengthsize_t
on your platform then select one of them:And I suggest using
stdint
types instead of raw data types for consistancy.我记得,唯一可移植的方法是将结果转换为“unsigned long int”并使用
%lu
。As I recall, the only portable way to do it, is to cast the result to "unsigned long int" and use
%lu
.使用“%zo”作为 off_t。 (八进制)
或“%zu”表示十进制。
use "%zo" for off_t. (octal)
or "%zu" for decimal.