284 votes

printf() de mise en forme pour hex

C'est plus une curieuse requête que d'une question importante, mais pourquoi lors de l'impression d'hex à 8 chiffres avec des zéros, ce n' %#08X affiche Pas le même résultat que l' 0x%08X?

Lorsque j'essaie d'utiliser l'ancien, l' 08 mise en forme de drapeau est supprimé, et il ne fonctionne pas avec juste 8.

De nouveau j'étais juste curieux.

421voto

Mike Points 16224

L' # partie vous donne un 0x dans la chaîne de sortie. L' 0 et de la x count contre votre "8" les caractères figurant dans l' 08 partie. Vous avez besoin de demander de 10 caractères si vous voulez qu'il soit le même.

int i = 7;

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

70voto

Random832 Points 9199

Le "0x" compte vers les huit caractères. Vous avez besoin d' "%#010x".

Notez que # ne pas ajouter le 0x 0 - le résultat sera 0000000000 - donc, vous avez probablement fait faut juste utiliser "0x%08x" de toute façon.

44voto

Jonathan Leffler Points 299946

L' %#08X de conversion doit précéder la valeur 0X; ce qui est requis par la norme. Il n'y a aucune preuve dans la norme que l' # doit modifier le comportement de l' 08 dans le cahier des charges, sauf que l' 0X préfixe est compté comme une partie de la longueur (de sorte que vous pouvez/devez utiliser %#010X. Si, comme moi, vous aimez votre hex présenté comme 0x1234CDEF, alors vous devez utiliser 0x%08X pour atteindre le résultat souhaité. Vous pouvez utiliser %#.8X et qui devrait également insérer des zéros à gauche.

Essayez de variations sur le code suivant:

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

Sur une RHEL 5 de la machine, et également sur Mac OS X (10.7.5), la sortie a été:

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

Je suis un peu surpris du traitement de l'0; je ne suis pas clair pourquoi l' 0X préfixe est omis, mais avec deux systèmes distincts de le faire, il doit être la norme. Il confirme mes préjugés à l'encontre de l' # option.


Le traitement de zéro est conforme à la norme.

ISO/IEC 9899:2011 §7.21.6.1 L' fprintf fonction

¶6 Le pavillon des personnages et leurs significations sont les suivantes:
...
# Le résultat est converti en une "autre forme". ... Pour x (ou X) la conversion, à un différent de zéro résultat a 0x (ou 0X) comme préfixe. ...

(Italiques ajoutés.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X