如何在C中打印int64_t类型

rta*_*oni 270 c stdint

C99标准具有整数类型,字节大小类似于int64_t.我使用以下代码:

#include <stdio.h>
#include <stdint.h>
int64_t my_int = 999999999999999999;
printf("This is my_int: %I64d\n", my_int);
Run Code Online (Sandbox Code Playgroud)

我得到这个编译器警告:

warning: format ‘%I64d’ expects type ‘int’, but argument 2 has type ‘int64_t’
Run Code Online (Sandbox Code Playgroud)

我尝试过:

printf("This is my_int: %lld\n", my_int); // long long decimal
Run Code Online (Sandbox Code Playgroud)

但我得到同样的警告.我正在使用这个编译器:

~/dev/c$ cc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5664~89/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5664)
Run Code Online (Sandbox Code Playgroud)

我应该使用哪种格式打印my_int变量而不发出警告?

oua*_*uah 394

对于int64_t类型:

#include <inttypes.h>
int64_t t;
printf("%" PRId64 "\n", t);
Run Code Online (Sandbox Code Playgroud)

对于uint64_t类型:

#include <inttypes.h>
uint64_t t;
printf("%" PRIu64 "\n", t);
Run Code Online (Sandbox Code Playgroud)

你也可以用PRIx64十六进制打印.

cppreference.com包含所有类型的可用宏的完整列表,包括intptr_t(PRIxPTR).scanf有单独的宏,比如SCNd64.


PRIu16的典型定义是"hu",因此隐式字符串常量级联在编译时发生.

为了使您的代码完全可移植,您必须使用PRId32等等进行打印int32_t,"%d"或者类似的打印int.

  • @Gaurav,这在某些平台上是正确的,但不是全部.例如,在我的amd64 Linux机器上,PRId64被定义为`ld`.可移植性是宏的原因. (22认同)
  • 格式宏常量的完整列表:http://en.cppreference.com/w/cpp/types/integer (17认同)
  • `PRId64`是一个内部转换为"lld"的宏.因此,它与编写`printf("%lld \n",t)一样好;`参见说明:http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic =% 2Fcom.qnx.doc.dinkum_en_c99%2Finttypes.html (14认同)
  • 而且,如果在Linux上使用C++,请确保在包含`inttypes.h`之前`#define __STDC_FORMAT_MACROS`. (12认同)
  • 我认为通过一些额外的努力,他们可能会使它更加令人讨厌 (4认同)
  • @Swift-FridayPie。“long”在 32 位 Linux 系统上为 32 位,在 64 位 Linux 系统上为 64 位。这就是为什么`PRId64`分别是`"lld"`和`"ld"`。这使得“long long”在未来变得比“long”更长。在短视平台上,即使在 64 位系统上,“long”也有 32 位,这使得“PRId64”在两种架构上都是“%lld”。 (2认同)
  • @r0ei 因为 `long` 不保证是 64 位。 (2认同)
  • @Roi您也不应该在无符号类型上使用“%ld”(或任何包含“d”的说明符)。等价的是`%lu`。请注意原因: `printf("%ld\n", ULONG_MAX);` 将在所有现代平台上打印 `-1`;显然负数不是“unsigned long”的最大值。除了您提供的内容之外,C 在运行时没有任何有关“printf”参数类型的信息。格式说明符告诉所需的输出格式*和*所提供参数的类型。使用错误的格式说明符可能会在某些平台上运行,但在其他平台上会崩溃,从而使您的程序不可移植。 (2认同)

pmg*_*pmg 60

C99的方式是

#include <inttypes.h>
int64_t my_int = 999999999999999999;
printf("%" PRId64 "\n", my_int);
Run Code Online (Sandbox Code Playgroud)

或者你可以投!

printf("%ld", (long)my_int);
printf("%lld", (long long)my_int); /* C89 didn't define `long long` */
printf("%f", (double)my_int);
Run Code Online (Sandbox Code Playgroud)

如果您坚持使用C89实现(特别是Visual Studio),您可以使用开源<inttypes.h>(和<stdint.h>):http://code.google.com/p/msinttypes/


pjh*_*sea 14

使用C99,%j长度修改器也可以与printf系列函数一起使用,以打印类型int64_t和值的值uint64_t:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    int64_t  a = 1LL << 63;
    uint64_t b = 1ULL << 63;

    printf("a=%jd (0x%jx)\n", a, a);
    printf("b=%ju (0x%jx)\n", b, b);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译此代码gcc -Wall -pedantic -std=c99不会产生任何警告,程序将打印预期的输出:

a=-9223372036854775808 (0x8000000000000000)
b=9223372036854775808 (0x8000000000000000)
Run Code Online (Sandbox Code Playgroud)

这是根据printf(3)我的Linux系统上(手册页明确指出,j用于指示转换到一个intmax_tuintmax_t;在我stdint.h,既int64_tintmax_t被typedef定义在完全相同的方式,同样的uint64_t).我不确定这是否完全可以移植到其他系统.

  • 如果`%jd`出现`intmax_t`,则正确的调用将是`printf("a =%jd(0x%jx)",(intmax_t)a,(intmax_t)a)`.无法保证`int64_t`和`intmax_t`是相同的类型,如果不是,则行为未定义. (10认同)
  • 您可以移植使用`%jd`来打印`int64_t`值*如果*在将它们传递给`printf`之前显式地将它们转换为`intmax_t`:`printf("a =%jd \n",(intmax_t)a) `.这避免了(<inttypes.h>`宏的(恕我直言)丑陋.当然这假设你的实现支持`%jd`,`int64_t`和`intmax_t`,所有这些都是由C99添加的. (2认同)
  • @KeithThompson “丑陋”说得实在是太友善了,伙计。这绝对是可怕的。太可怕了。真令人作呕。令人尴尬的是它是什么。或者至少他们应该感到尴尬,介绍这个的人。我从未见过这些宏,但按照这个答案和评论(包括您的评论)的建议进行操作。 (2认同)

ata*_*xic 7

来自嵌入式世界,甚至uclibc并不总是可用,代码就像

uint64_t myval = 0xdeadfacedeadbeef; printf("%llx", myval);

是打印废话或根本不工作 - 我总是使用一个小助手,允许我正确转储uint64_t十六进制:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

char* ullx(uint64_t val)
{
    static char buf[34] = { [0 ... 33] = 0 };
    char* out = &buf[33];
    uint64_t hval = val;
    unsigned int hbase = 16;

    do {
        *out = "0123456789abcdef"[hval % hbase];
        --out;
        hval /= hbase;
    } while(hval);

    *out-- = 'x', *out = '0';

    return out;
}
Run Code Online (Sandbox Code Playgroud)


ben*_*ong 5

在Windows环境中,使用

%I64d
Run Code Online (Sandbox Code Playgroud)

在Linux中,使用

%lld
Run Code Online (Sandbox Code Playgroud)

  • `%lld`是`long long int`的格式,*不一定与`int64_t`相同.`<stdint.h>`有一个宏,用于`int64_t`的正确格式; 见[ouah的回答](http://stackoverflow.com/a/9225648/827263). (15认同)