【问题标题】:cross-platform printing of 64-bit integers with printf使用 printf 跨平台打印 64 位整数
【发布时间】:2011-06-09 20:49:18
【问题描述】:

在 Windows 中,它是“%I64d”。在 Linux 和 Solaris 中,它是“%lld”。
如果我想编写打印long long 值的跨平台printfs:这样做的好方法是什么?

long long ll;
printf(???, ll);

【问题讨论】:

  • 显然我需要#if defined(WIN32) && !defined(PRId64) \n #define PRId64 "I64d" \n #endif.感谢所有回答的人。
  • 您还应该查看您的类型,如果它们不可用,请使用 typedef 替换 [u]int64_t
  • 64位整数和长整数有什么区别?我正在阅读其他人的程序,他们使用 PRId64,我不明白。

标签: c printf


【解决方案1】:

有几种方法。

您可以以符合 C99 的方式编写代码,然后在编译器编写者让您失望时提供特定于系统的 hack。 (遗憾的是,这在 C99 中相当普遍。)

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

如果您的某个目标系统忽略了实现 &lt;inttypes.h&gt; 或者由于某些类型功能是可选的而以某种其他方式严重懈怠,那么您只需要针对 PRId64 的系统特定 #define (或其他)在该系统上。

另一种方法是选择当前始终实现为 64 位且受 printf 支持的内容,然后进行强制转换。不完美,但通常会这样做:

printf("My value is %10lld\n", (long long)some_64_bit_expression);

【讨论】:

  • 您没有说出您要打印的确切类型,但正如其他人所指出的,PRId64 专门用于int64_t。如果你使用&lt;stdint.h&gt;,那么 printf 应该有一个对应的&lt;inttypes.h&gt; 宏。
  • 我想接受两个答案,DigitalRoss 和 Random832,不知道该怎么做。元论坛上的文件请求。
  • 迟到的评论,但我错过了在PRId64之前的字符串中我仍然需要%,否则它抱怨some_64_bit_expression出乎意料:printf("Foo %" PRId64, some_64_bit_expression);
【解决方案2】:

MSVC 支持 long longll 开始 Visual Studio 2005

您可以检查 _MSC_VER macro 的值(&gt;= 1400 表示 2005 年),或者干脆不支持较旧的编译器。

它不提供 C99 宏,因此您必须转换为 long long 而不是使用 PRId64

如果您将旧版 MSVC 库与非 MSVC 编译器一起使用,这将无济于事(我认为 mingw 至少提供了自己的支持 ll 的 printf 版本)

【讨论】:

  • 看起来 MS 为 msvcrt.dll 添加了ll 修饰符支持(至少在我的 Win7 机器上)。我对此感到惊讶。看起来 MinGW 并没有做任何特别的事情来支持它(上次我尝试将 ll 与 MinGW 一起使用它失败了)。
  • 谢谢。我从来不知道 MSVC 支持 %lld。
  • 我想接受两个答案,DigitalRoss 和 Random832,不知道该怎么做。元论坛上的文件请求。
【解决方案3】:

在 linux 和 solaris 上没有,只是顺便说一下,这是 lld 用于 64 位类型。 C99 规定了简单(但丑陋)的宏来使这些东西可移植PRId64。由于某些 Windows 编译器不遵循标准,因此很遗憾,您可能不走运。

编辑:在您的示例中,您使用的是与 64 位整数不同的东西,即 long long。在某些架构上,这很可能是 128。这里 C99 有 typedefs 来保证类型的最小或精确宽度(如果它们在平台上实现)。这些类型在inttypes.h 标头中找到,即int64_t 表示以二进制补码表示的固定宽度64 位类型。也许你的 Windows 编译器没有这个。

【讨论】:

  • 注意:PRId64 宏用于打印int64_t,而不是long long
  • @Dietrich,没错。我这样解释问题的标题。不过你说得对,我加了一条关于long long的评论。
【解决方案4】:

作为替代方案,您可以使用如下代码:

uint64_t currentTimeMs = ...;

printf("currentTimeMs = 0x%08x%08x\n",
            (uint32_t)(currentTimeMs >> 32),
            (uint32_t)(currentTimeMs & 0xFFFFFFFF)
    );

或许:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );

【讨论】:

  • "%u%09u" 不幸地将 16 格式化为 000000016,这在最坏的情况下可能看起来像一个八进制数,在最好的情况下可能看起来很奇怪。
猜你喜欢
  • 1970-01-01
  • 2013-12-14
  • 2020-06-07
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2019-07-06
  • 2013-06-02
  • 1970-01-01
相关资源
最近更新 更多