【问题标题】:Is there a way to print long int and int with the same format flag?有没有办法用相同的格式标志打印 long int 和 int ?
【发布时间】:2012-03-14 13:48:11
【问题描述】:

我有一个定义索引类型的代码,这样如果用户知道他们的索引空间保持在普通整数的范围内,他们可以使用int 而不是long int

    #ifdef LONG_IDX
    typedef long int idx_type
    #else
    typedef int idx_type
    #endif

我的代码中有一些printf 语句来打印出这个索引数据,我不想将它们包装在到处都是#ifdef 语句中。是否有格式标志来指定参数可能是long intint?如果没有,有没有办法定义一个自定义格式标志,我可以简单地添加到我的索引类型定义中?

【问题讨论】:

  • 我猜 C++ 对此的回答是停止使用 printf 而是使用 cout 样式输出。
  • 如果您需要格式字符串,请使用 boost 格式和位置格式说明符
  • 您的文字显示为long int,但您的代码显示为long long int
  • 我相信@Damien_The_Unbeliever。 :)
  • 答案取决于这是 C 代码还是 C++ 代码。两者都被标记了。您需要 C 答案吗?

标签: c++ c printf


【解决方案1】:

您可以有条件地为您的索引类型定义格式化程序:

#ifdef LONG_IDX
typedef long long int idx_type
#define IDX_FORMAT "lld"
#else
typedef int idx_type
#define IDX_FORMAT "d"
#endif

那么您当然需要在格式化调用中使用它,这可能会变得有点麻烦,并且(一如既往!)需要您保持警惕并记住在您想要打印索引时正确执行:

idx_type my_index = 47;

print("my_index = %" IDX_FORMAT, my_index);

请注意上面如何使用 C 的相邻字符串文字的自动连接来在编译时“构建”正确的格式化字符串。这是 C 语法中令人敬畏的特性的典型用法。

此外,如果您的编译器足以进行格式化字符串验证(GCC 可以),那么如果您搞砸并忘记在某处使用 defined 字符串,您很可能会收到有用的警告。

【讨论】:

  • 这就是我的做法。这个问题同时用 C 和 C++ 标记,这在两者中都适用。所以+1。不过,我也很喜欢 Richard 回答的简洁和优雅。
  • "%j" 和投射到 intmax_t 有什么问题?这就是它们的设计目的。
  • @James 我在我常用的资源 (c++.com) 中没有看到任何关于 %j 标志的真实文档,您能否指出一个好的来源?
  • @Mosby 我通常使用单一 UNIX 规范:您必须在 unix.org/online.html 注册。该规范包括 Posix 和 Open Group 所需的扩展,但它们都已明确标识。 (Linux 手册页也很好,但它们不区分什么是 Unix 扩展,什么不是。)如果不出意外,维基百科也描述了 "%j"。但这并不多:它只是以下格式说明符的宽度修饰符,例如"%jd""%d" 一样,只是它需要一个 intmax_t。 (请注意,它是 C99,而不是 C90。)
【解决方案2】:

我会使用%lli(long long integer),并在打印时进行强制转换:

idx_type idx;

printf("%lli", (long long int) idx);

我认为这可以让您最可靠地了解将要打印的内容。

【讨论】:

  • 在这种情况下。一般的解决方案是使用"%j" 并转换为intmax_t。 (当然,这是 C++ 程序员没有的问题。)
【解决方案3】:

最简单的方法是总是“向上”。

#include <stdio.h>

int main(void)
{
    char c = 1;
    int i = 12;
    long int l = 123;
    long long int ll = 1234;

    printf("c=%lld i=%lld l=%lld ll=%lld\n", 
            (long long int) c, 
            (long long int) i, 
            (long long int) l, 
            (long long int) ll
          );
    return 0;
}

【讨论】:

  • @Richard:你认为你的格式风格是优越的?我更喜欢在行首使用 kommaas,因为这样会更突出。
  • 这不是关于逗号,而是关于行缩进。如果您愿意,可以将它改回来,只要确保缩进便于阅读即可。
  • 你可以缩进任何你想要的,但不要碰我的逗号。顺便说一句,即使我没有在第一个大括号处缩进(我从不缩进),代码也是可读的。 BTW2:你为什么不清理初始化程序附近的草率空白?
【解决方案4】:

在 printf 或 std::cout 打印中使用 %d 表示十进制。

【讨论】:

  • %d%i 相同,意思就是int
  • 哦该死的。我的 C 确实有点生锈了。
猜你喜欢
  • 2023-03-30
  • 2021-06-25
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多