printf()格式为十六进制

wsm*_*ker 165 c printf hex

这是一个奇怪的查询而不是一个重要的问题,但为什么当将十六进制打印为带有前导零的8位数字时,为什么这%#08X不显示相同的结果0x%08X

当我尝试使用前者时,08格式化标志被删除,并且它不能正常使用8.

我只是好奇.

Mik*_*ike 255

#部分为您提供0x输出字符串.在0x反对在列出的"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
Run Code Online (Sandbox Code Playgroud)

同样改变的情况x,影响输出字符的外壳.

printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB
Run Code Online (Sandbox Code Playgroud)

  • 注意,如果`i = 0;`,使用`%#`的版本将不包含`0x`前缀. (17认同)

Ran*_*832 51

"0x"计入八个字符计数.你需要"%#010x".

请注意,#没有在0X追加到0 -结果将是0000000000-所以你可能实际上应该只使用"0x%08x"反正.

  • 感谢您指出“#”不会将“0x”添加到“0”前面! (3认同)

Jon*_*ler 31

所述%#08X转换必须与前面的值0X; 这是标准所要求的.标准中没有证据表明#应该改变08规范部分的行为,除了0X前缀被计为长度的一部分(所以你可能想要/需要使用%#010X.如果像我一样,你喜欢你的十六进制表示为0x1234CDEF,然后你必须用来0x%08X达到理想的结果.你可以使用%#.8X,也应该插入前导零.

尝试以下代码的变体:

#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);
}
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

我对0的治疗感到有些惊讶; 我不清楚为什么0X省略前缀,但是有两个独立的系统在做,它必须是标准的.它证实了我对该#选择的偏见.


零的处理是根据标准.

ISO/IEC 9899:2011§7.21.6.1 fprintf功能

6标志字符及其含义是:
...
#结果转换为"替代形式"....对于x(或X)转换,非零结果具有0x(或0X)前缀....

(重点补充.)


chq*_*lie 6

#导致0x(或0Xfor %#X)被附加到输出,除非值是0,所以#如果你想你不应该使用0x总是出现在输出中。

您可以将宽度字段与0标志结合使用以生成前导零:%08x将带有前导零的数字填充到8. 如果您希望所有 32 位值的输出一致,请使用"0x08x".

您还可以使用 precision 字段:%.8x将带有前导零的8数字填充到总位数。因此你也可以使用"0x%.8x"用于您的目的。

如果前缀作为转换,如的一部分生成这些转换规范将不同0x#-在签署转换为负数,其长度进行计数的宽度但不适合精度说明。此外, precision 字段可以与 width 字段结合使用:

printf("|%10x|", 256)      // outputs |       100|
printf("|%010x|", 256)     // outputs |0000000100|
printf("|%#010x|", 256)    // outputs |0x00000100|

printf("|%10.8x|", 256)    // outputs |  00000100|
printf("|%#10.8x|", 256)   // outputs |0x00000100|
printf("|0x%.8x|", 256)    // outputs |0x00000100|

printf("|%10x|", 0)        // outputs |         0|
printf("|%010x|", 0)       // outputs |0000000000|
printf("|%#010x|", 0)      // outputs |0000000000|

printf("|%10.8x|", 0)      // outputs |  00000000|
printf("|%#10.8x|", 0)     // outputs |  00000000|
printf("|0x%.8x|", 0)      // outputs |0x00000000|
Run Code Online (Sandbox Code Playgroud)

我建议使用最后一个:"0x%.8x".