如何打印类型未知大小一样的ino_t过去? [英] How to print types of unknown size like ino_t?

查看:905
本文介绍了如何打印类型未知大小一样的ino_t过去?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里我想与的printf 打印整型实现定义尺寸(如的价值ino_t过去 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 (like ino_t or time_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 modifier

Specifies that a following d, i, o, u, x, or X conversion specifier applies to an intmax_t or uintmax_t argument; or that a following n conversion specifier applies to a pointer to an intmax_t argument.

There are also z and t modifiers for size_t and ptrdiff_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 use uintmax_t and get well-defined results for all values, though printing -1 as 18446744073709551615 (264-1) may be a bit confusing.

All of this works only if your C implementation supports <stdint.h> and the j length modifier for printf -- i.e., if it supports C99. Not all compilers do so (coughMicrosoftcough). For C90, the widest integer types are long and unsigned 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 than long and unsigned long as an extension.

这篇关于如何打印类型未知大小一样的ino_t过去?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆