什么是适当的使用printf显示指针以0填充
题
在C,我想到使用printf显示指针,以便他们行正确的,我想垫他们0。
我的猜测是正确的方式做这是:
printf("%016p", ptr);
这一工作,但这个海湾合作委员会抱怨与以下信息:
warning: '0' flag used with ‘%p’ gnu_printf format
我已经google搜索一位,以下线是关于同一主题的,但是并没有真正得到一个解决方案。
http://gcc.gnu.org/ml/gcc-bugs/2003-05/msg00484.html
阅读它,它似乎是原因,海湾合作委员会抱怨是,我的语法建议中未定义C99。但我似乎找不到任何其他方式做同样的事情在标准的核准方式。
因此,这里的双重问题:
- 我的理解是正确的,这种行为是不是定义的C99标准?
- 如果是这样,是否有一个标准获得批准,便携式的方式这样做?
解决方案
#include <inttypes.h>
#include <stdint.h>
printf("%016" PRIxPTR "\n", (uintptr_t)ptr);
但是它不会打印指针在执行定义的方式(说 DEAD:BEEF
为8086分割的模式)。
其他提示
使用:
#include <inttypes.h>
printf("0x%016" PRIXPTR "\n", (uintptr_t) pointer);
或用另一个变体的宏从那头。
还注意到,一些实现 printf()
印'0x
'前面的指针;其他人不这样做(以及两者都是正确的根据C的标准)。
唯一的 便携式 的方式来打印指针的价值是使用 "%p"
说明符,其产生的执行情况定义的输出。(转换到 uintptr_t
和使用 PRIxPTR
是有可能的工作,但(a) uintptr_t
介绍了在C99,所以有些编制者使用时就会不支持它,以及(b)它不能保证存在,甚至在C99(有可能不是一个整数类型的大到足以容纳所有可能的指数值。
因此,使用 "%p"
与 sprintf()
(或 snprintf()
, 如果你有的话),打印的字符串,然后打印的字符串填充有领先的空白。
一个问题是,有没有真的很好的方式确定的最长的字符串产生的 "%p"
.
这是无可否认的不便(虽然你当然可以包装在一个功能)。如果你不需要100%的携带,我从来没有使用的系统被铸造的指针 unsigned long
和打印结果的使用 "0x%16lx"
不会的工作。[更新:是的,我有。64位Windows有64位的指针,以及32位的 unsigned long
.] (或者您可以使用 "0x%*lx"
和计算宽,可能喜欢的东西 sizeof (void*) * 2
.如果你真偏执,你可以考虑的系统 CHAR_BIT > 8
, 所以你会得到超过2hex digits每字节。)
这答案是相似的一个鉴于早些时候在 https://stackoverflow.com/a/1255185/1905491 但是还需要尽可能宽度的入账户(所概述的通过 https://stackoverflow.com/a/6904396/1905491 我没有认识到直到我的回答是呈现下它;)。以下剪将打印的指针为8 0-通过六角字上的明智*机在那里他们可以表示的32位,16 64和4月16b系统。
#include <inttypes.h>
#define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))
printf("0x%0*" PRIxPTR, PRIxPTR_WIDTH, (uintptr_t)pointer);
注意使用星号的字取宽度的下一论点,这是在C99(可能是之前吗?), 但这是很少见的"在野"。这是更好的方式比使用 p
转换,因为后者是执行定义。
*该标准允许 uintptr_t
要大于最小,但我认为,没有执行,不使用最低限度。
这很容易解决,如果你投的指针指向一个很长的类型。问题是这不会在所有的平台,因为它假定一个指针可能适合内部的一个长期的,而这一指针可以显示,在16个字符的(64位)。但是,这是真正的大多数平台。
因此,它将成为:
printf("%016lx", (unsigned long) ptr);
作为你的链路已经表明,行为是不确定的。我不认为有一个便携式的方式这样做%p本身取决于在平台上你的工作。你当然可以只把指针指向一个int,并显示它在hex:
printf("0x%016lx", (unsigned long)ptr);
也许这会很有趣的(从一个32位的windows的机器,使用mingw):
rjeq@RJEQXPD /u
$ cat test.c
#include <stdio.h>
int main()
{
char c;
printf("p: %016p\n", &c);
printf("x: %016llx\n", (unsigned long long) (unsigned long) &c);
return 0;
}
rjeq@RJEQXPD /u
$ gcc -Wall -o test test.c
test.c: In function `main':
test.c:7: warning: `0' flag used with `%p' printf format
rjeq@RJEQXPD /u
$ ./test.exe
p: 0022FF77
x: 000000000022ff77
正如你可以看到,该%p版垫零尺寸大小的指针,然后空间指定的大小,而在使用%x和转换(在转换和格式说明是高度无法移植)使用仅零。
注意,如果指针指纹与"0x"前缀,你会需要的替代品"%018p"补偿。
我通常使用%x显示指针。我想这不是便携式的64位系统上,但它的工作的现用于32苦.
我将有兴趣看到什么答案有用 便携式解决方案, ,因为指针的表示是不完全的便携式。