C语言 printf() 十六进制格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14733761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
printf() formatting for hex
提问by wsmccusker
This is more of a curious query than an important question, but why when printing hex as an 8 digit number with leading zeros, does this %#08XNot display the same result as 0x%08X?
这更像是一个奇怪的查询而不是一个重要的问题,但是为什么在将十六进制打印为带有前导零的 8 位数字时,这%#08X不会显示与0x%08X?
When I try to use the former, the 08formatting flag is removed, and it doesn't work with just 8.
当我尝试使用前者时,08格式化标志被删除,并且它不适用于8.
Again I was just curious.
再次,我只是好奇。
回答by Mike
The #part gives you a 0xin the output string. The 0and the xcount against your "8" characters listed in the 08part. You need to ask for 10 characters if you want it to be the same.
该#部分0x在输出字符串中为您提供 a 。在0和x反对在列出的“8”字计数08的一部分。如果您希望它相同,则需要要求 10 个字符。
int i = 7;
printf("%#010x\n", i); // gives 0x00000007
printf("0x%08x\n", i); // gives 0x00000007
printf("%#08x\n", i); // gives 0x000007
Also changing the case of x, affects the casing of the outputted characters.
更改 , 的大小写x也会影响输出字符的大小写。
printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB
回答by Random832
The "0x" counts towards the eight character count. You need "%#010x".
“0x”计入八个字符的计数。你需要"%#010x".
Note that #does notappend the 0x to 0 - the result will be 0000000000- so you probably actually should just use "0x%08x"anyway.
请注意,#并没有在0X追加到0 -结果将是0000000000-所以你可能实际上应该只使用"0x%08x"反正。
回答by Jonathan Leffler
The %#08Xconversion must precede the value with 0X; that is required by the standard. There's no evidence in the standard that the #should alter the behaviour of the 08part of the specification except that the 0Xprefix is counted as part of the length (so you might want/need to use %#010X. If, like me, you like your hex presented as 0x1234CDEF, then you have to use 0x%08Xto achieve the desired result. You could use %#.8Xand that should also insert the leading zeroes.
所述%#08X转换必须与前面的值0X; 这是标准所要求的。标准中没有证据表明#应该改变08规范部分的行为,除了0X前缀被算作长度的一部分(所以你可能想要/需要使用%#010X。如果像我一样,你喜欢你的十六进制表示为0x1234CDEF, 那么你必须使用0x%08X来达到预期的结果。你可以使用%#.8Xand that 也应该插入前导零。
Try variations on the following code:
尝试以下代码的变体:
#include <stdio.h>
int main(void)
{
int j = 0;
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
for (int i = 0; i < 8; i++)
{
j = (j << 4) | (i + 6);
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
}
return(0);
}
On an RHEL 5 machine, and also on Mac OS X (10.7.5), the output was:
在 RHEL 5 机器和 Mac OS X (10.7.5) 上,输出为:
0x00000000 = 00000000 = 00000000 = 0000000000
0x00000006 = 0X000006 = 0X00000006 = 0x00000006
0x00000067 = 0X000067 = 0X00000067 = 0x00000067
0x00000678 = 0X000678 = 0X00000678 = 0x00000678
0x00006789 = 0X006789 = 0X00006789 = 0x00006789
0x0006789A = 0X06789A = 0X0006789A = 0x0006789a
0x006789AB = 0X6789AB = 0X006789AB = 0x006789ab
0x06789ABC = 0X6789ABC = 0X06789ABC = 0x06789abc
0x6789ABCD = 0X6789ABCD = 0X6789ABCD = 0x6789abcd
I'm a little surprised at the treatment of 0; I'm not clear why the 0Xprefix is omitted, but with two separate systems doing it, it must be standard. It confirms my prejudices against the #option.
我对 0 的处理有点惊讶;我不清楚为什么0X省略前缀,但有两个独立的系统这样做,它必须是标准的。它证实了我对这个#选项的偏见。
The treatment of zero is according to the standard.
零的处理按标准执行。
ISO/IEC 9899:2011 §7.21.6.1 The
fprintffunction?6 The flag characters and their meanings are:
...#The result is converted to an "alternative form". ... Forx(orX) conversion, a nonzeroresult has0x(or0X) prefixed to it. ...
ISO / IEC 9899:2011 §7.21.6.1的
fprintf功能?6 标志字符及其含义是:
...#结果被转换为“替代形式”。... 对于x(或X)转换,非零结果具有0x(或0X)前缀。...
(Emphasis added.)
(加了重点。)
Note that using %#Xwill use upper-case letters for the hex digits and 0Xas the prefix; using %#xwill use lower-case letters for the hex digits and 0xas the prefix. If you prefer 0xas the prefix and upper-case letters, you have to code the 0xseparately: 0x%X. Other format modifiers can be added as needed, of course.
请注意, using%#X将使用大写字母作为十六进制数字并0X作为前缀;using%#x将使用小写字母作为十六进制数字和0x前缀。如果您更喜欢0x前缀和大写字母,则必须分别编码0x:0x%X. 当然,可以根据需要添加其他格式修饰符。
For printing addresses, use the <inttypes.h>header and the uintptr_ttype and the PRIXPTRformat macro:
对于打印地址,请使用<inttypes.h>标题、uintptr_t类型和PRIXPTR格式宏:
#include <inttypes.h>
#include <stdio.h>
int main(void)
{
void *address = &address; // &address has type void ** but it converts to void *
printf("Address 0x%.12" PRIXPTR "\n", (uintptr_t)address);
return 0;
}
Example output:
示例输出:
Address 0x7FFEE5B29428
Choose your poison on the length — I find that a precision of 12 works well for addresses on a Mac running macOS. Combined with the .to specify the minimum precision (digits), it formats addresses reliably. If you set the precision to 16, the extra 4 digits are always 0 in my experience on the Mac, but there's certainly a case to be made for using 16 instead of 12 in portable 64-bit code (but you'd use 8 for 32-bit code).
选择长度上的毒药——我发现 12 的精度适用于运行 macOS 的 Mac 上的地址。结合.以指定最小精度(数字),它可靠地格式化地址。如果您将精度设置为 16,根据我在 Mac 上的经验,额外的 4 位数字始终为 0,但在便携式 64 位代码中肯定需要使用 16 而不是 12(但您会使用 8 32 位代码)。

