如何打印类型未知大小一样的ino_t过去? [英] How to print types of unknown size like ino_t?
问题描述
我在这里我想与的printf
打印整型实现定义尺寸(如的价值ino_t过去$经常遇到的情况C $ C>或
time_t的
)。现在,我使用这样一种模式,这样的:
的#include< inttypes.h>ino_t过去伊诺; / *未知大小的变量* /
的printf(%PRIuMAX,(uintmax_t型)氨基);
此方法适用到目前为止,但它有几个缺点:
- 我要知道我想要的打印类型是否带符号。
- 我必须用一个类型转换的可能扩大我的code。
有没有更好的策略是什么?
的#include< inttypes.h>
ino_t过去伊诺; / *未知大小的变量* /
/ * ... * /
的printf(%PRIuMAX,(uintmax_t型)氨基);
这肯定会工作(有一些限制性条款,见下文),但我会用:
的printf(%菊(uintmax_t型)氨基);
的Ĵ
长度修改
指定后续的
D
I
,0
U
X
或X
转换说明适用于一个< STRONG>还会将intmax_t
或uintmax_t型
参数;或者说一个如下的N
转换
说明适用于一个指向还会将intmax_t
参数。
块引用>也有
以Z
和T
修饰符为size_t
和ptrdiff_t的
(及其相应符号/无符号类型),分别为。和个人而言,我觉得在
中所定义的格式字符串宏; inttypes.h&GT;
难看又难记,这就是为什么我preFER菊%
或JD%
。正如你所提到的,它有助于知道类型(
ino_t过去
在这种情况下)是否带符号。如果你不知道发生的是,它可能看着办吧:的#include&LT;&stdio.h中GT;
#包括LT&;&stdint.h GT;
#包括LT&; SYS / types.h中&GT;的#define IS_SIGNED(型)((型)-1≤(型)0)
#定义DECIMAL_FORMAT(类型)(IS_SIGNED(类型)JD%:举%)
#定义CONVERT_TO_MAX(类型,值)\\
(IS_SIGNED(类型)(还会将intmax_t)(值):?(uintmax_t型)(值))
#定义PRINT_VALUE(类型,值)\\
(printf的(DECIMAL_FORMAT(类型),CONVERT_TO_MAX(类型,(价值))))诠释主要(无效){
伊诺ino_t过去= 42;
PRINT_VALUE(ino_t过去,氨基);
的putchar('\\ n');
}尽管这可能是矫枉过正。如果你确定类型为窄于64位,可以将值
转换还会将intmax_t
,和值将是preserved。或者你可以使用uintmax_t型
,并得到所有值定义良好的结果,尽管印刷1
为18446744073709551615
(2 64 -1)可能是一个有点混乱。所有这些工作只有当您的C实现支持
&LT; stdint.h&GT;
和Ĵ
长度修改为的printf
- 也就是说,如果它支持C99。并非所有的编译器这样做(咳嗽微软咳嗽)。对于C90,最宽的整数类型长
和无符号长
,并且可以转换为那些并使用%ld的
和/或%lu个
。您可以使用__ STDC_VERSION __
predefined宏观理论测试C99合规性 - 尽管有些pre-C99编译器可能仍然支持类型比长
和无符号长
作为扩展。I often experience situations where I want to print with
printf
the value of an integer type of implementation-defined size (likeino_t
ortime_t
). Right now, I use a pattern like this for this:#include <inttypes.h> ino_t ino; /* variable of unknown size */ printf("%" PRIuMAX, (uintmax_t)ino);
This approach works so far but it has a couple of disadvantages:
- I have to know whether the type I'm trying print is signed or unsigned.
- I have to use a type cast that possibly enlarges my code.
Is there a better strategy?
解决方案#include <inttypes.h> ino_t ino; /* variable of unknown size */ /* ... */ printf("%" PRIuMAX, (uintmax_t)ino);
That will certainly work (with some provisos; see below), but I'd use:
printf("%ju", (uintmax_t)ino);
The
j
length modifierSpecifies that a following
d
,i
,o
,u
,x
, orX
conversion specifier applies to anintmax_t
oruintmax_t
argument; or that a followingn
conversion specifier applies to a pointer to anintmax_t
argument.There are also
z
andt
modifiers forsize_t
andptrdiff_t
(and their corresponding signed/unsigned types), respectively.And personally, I find the format string macros defined in
<inttypes.h>
ugly and difficult to remember, which is why I prefer"%ju"
or"%jd"
.As you mentioned, it's helpful to know whether the type (
ino_t
in this case) is signed or unsigned. If you don't happen to know that, it's possible to figure it out:#include <stdio.h> #include <stdint.h> #include <sys/types.h> #define IS_SIGNED(type) ((type)-1 < (type)0) #define DECIMAL_FORMAT(type) (IS_SIGNED(type) ? "%jd" : "%ju") #define CONVERT_TO_MAX(type, value) \ (IS_SIGNED(type) ? (intmax_t)(value) : (uintmax_t)(value)) #define PRINT_VALUE(type, value) \ (printf(DECIMAL_FORMAT(type), CONVERT_TO_MAX(type, (value)))) int main(void) { ino_t ino = 42; PRINT_VALUE(ino_t, ino); putchar('\n'); }
though that may be overkill. If you're sure the type is narrower than 64 bits, you can convert the value to
intmax_t
, and the value will be preserved. Or you can useuintmax_t
and get well-defined results for all values, though printing-1
as18446744073709551615
(264-1) may be a bit confusing.All of this works only if your C implementation supports
<stdint.h>
and thej
length modifier forprintf
-- i.e., if it supports C99. Not all compilers do so (coughMicrosoftcough). For C90, the widest integer types arelong
andunsigned long
, and you can convert to those and use"%ld"
and/or"%lu"
. You can theoretically test for C99 compliance using the__STDC_VERSION__
predefined macro -- though some pre-C99 compilers might still support types wider thanlong
andunsigned long
as an extension.这篇关于如何打印类型未知大小一样的ino_t过去?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!