it-swarm.com.de

printf () Formatierung für hex

Dies ist eher eine merkwürdige Frage als eine wichtige Frage. Warum wird beim Drucken von Hex als 8-stellige Zahl mit führenden Nullen %#08X nicht dasselbe Ergebnis wie 0x%08X angezeigt?

Wenn ich versuche, das erstere zu verwenden, wird das Formatierungsflag 08 entfernt, und es funktioniert nicht nur mit 8.

Wieder war ich nur neugierig.

154
wsmccusker

Der Teil # gibt Ihnen einen 0x in der Ausgabezeichenfolge. Der 0 und der x werden auf Ihre "8" -Zeichen angerechnet, die im Teil 08 aufgeführt sind. Sie müssen nach 10 Zeichen fragen, wenn Sie möchten, dass es dasselbe ist.

int i = 7;

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

Das Ändern der Schreibweise von x wirkt sich auch auf die Schreibweise der ausgegebenen Zeichen aus.

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

Das "0x" wird auf die acht Zeichen angerechnet. Du brauchst "%#010x".

Beachten Sie, dass #nicht 0x an 0 anfügt - das Ergebnis ist 0000000000 - Sie sollten also wahrscheinlich nur "0x%08x" verwenden.

51
Random832

Die %#08X -Umwandlung muss dem Wert 0X vorangehen. das verlangt der standard. Es gibt keine Hinweise in der Norm, dass der # das Verhalten des 08 -Teils der Spezifikation ändern sollte, mit der Ausnahme, dass das 0X -Präfix als Teil der Länge gezählt wird (also möchten Sie vielleicht/Müssen Sie %#010X verwenden. Wenn Sie wie ich Ihr Hex als 0x1234CDEF präsentieren möchten, müssen Sie 0x%08X verwenden, um das gewünschte Ergebnis zu erzielen. Sie könnten %#.8X verwenden. und das sollte auch die führenden Nullen einfügen.

Probieren Sie Variationen des folgenden Codes aus:

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

Auf einem RHEL 5-Computer und auch unter Mac OS X (10.7.5) lautete die Ausgabe:

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

Ich bin ein wenig überrascht über die Behandlung von 0; Mir ist nicht klar, warum das Präfix 0X weggelassen wird, aber bei zwei separaten Systemen muss es Standard sein. Es bestätigt meine Vorurteile gegenüber der Option #.


Die Behandlung von Null entspricht dem Standard.

ISO/IEC 9899: 2011 §7.21.6.1 Die Funktion fprintf

¶6 Die Flaggenzeichen und ihre Bedeutung sind:
...
# Das Ergebnis wird in eine "alternative Form" umgewandelt. ... Für x (oder X) Konvertierung eine ungleich Null Dem Ergebnis ist 0x (oder 0X) vorangestellt. ...

(Betonung hinzugefügt.)


Beachten Sie, dass bei Verwendung von %#X Großbuchstaben für die Hexadezimalziffern und 0X als Präfix verwendet werden. Bei Verwendung von %#x werden Kleinbuchstaben für die hexadezimalen Ziffern und 0x als Präfix verwendet. Wenn Sie 0x als Präfix und Großbuchstaben bevorzugen, müssen Sie 0x separat codieren: 0x%X. Natürlich können bei Bedarf weitere Formatmodifikatoren hinzugefügt werden.

Verwenden Sie zum Drucken von Adressen den Header <inttypes.h> und den Typ uintptr_t sowie das Formatmakro 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;
}

Beispielausgabe:

Address 0x7FFEE5B29428

Wählen Sie Ihr Gift für die Länge - Ich finde, dass eine Genauigkeit von 12 für Adressen auf einem Mac mit macOS gut funktioniert. In Kombination mit dem . zur Angabe der Mindestgenauigkeit (Ziffern) werden Adressen zuverlässig formatiert. Wenn Sie die Genauigkeit auf 16 setzen, sind die zusätzlichen 4 Stellen nach meiner Erfahrung auf dem Mac immer 0, aber es gibt sicherlich einen Grund, 16 anstelle von 12 in portablem 64-Bit-Code zu verwenden (aber Sie würden 8 für verwenden) 32-Bit-Code).

27