printf()格式为十六进制

时间:2013-02-06 16:20:07

标签: c printf hex

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

当我尝试使用前者时,08格式标记将被删除,并且仅对8不起作用。

我再次感到好奇。

5 个答案:

答案 0 :(得分:238)

#部分在输出字符串中为您提供0x。对0部分中列出的“8”字符的x08计数。如果你想要它是相同的,你需要要10个字符。

int i = 7;

printf("%#010x\n", i);  // gives 0x00000007
printf("0x%08x\n", i);  // gives 0x00000007
printf("%#08x\n", i);   // gives 0x000007

同时更改x的大小写会影响输出字符的大小。

printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB

答案 1 :(得分:51)

“0x”计入八个字符数。您需要"%#010x"

请注意# 将0x附加到0 - 结果将是0000000000 - 所以你可能实际上应该只使用"0x%08x"。< / p>

答案 2 :(得分:24)

%#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);
}

在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

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


零处理符合标准。

  

ISO / IEC 9899:2011§7.21.6.1 fprintf功能

     

¶6旗帜字符及其含义如下:
  ...
  #结果转换为“替代形式”。 ...对于x(或X)   转换时, 非零 结果以0x(或0X)为前缀。 ...

(强调补充。)

答案 3 :(得分:4)

# 导致 0x(或 0X for %#X)被添加到输出中,除非值是 0,所以你不应该使用 { {1}} 如果您希望 # 始终出现在输出中。

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

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

如果前缀作为转换的一部分生成,则这些转换规范会有所不同,例如 "0x%.8x" 表示 0x# 表示带符号转换中的负数,其长度计入宽度但不是精度说明符。此外,精度字段可以与宽度字段组合:

-

我建议使用最后一个: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|

答案 4 :(得分:-1)

您始终可以使用“%p”来显示 8 位十六进制数。

int main (void)
{
    uint8_t a;
    uint32_t b;
    a = 15;
    b = a << 28;
    printf("%p", b);
    return 0;
}

输出:

0xf0000000
相关问题