printf() Formatierung für hexadezimal

Lesezeit: 7 Minuten

Benutzeravatar von wsmccusker
wsmcusker

Warum, wenn eine Zahl hexadezimal als 8-stellige Zahl mit führenden Nullen gedruckt wird? %#08X nicht dasselbe Ergebnis anzeigen wie 0x%08X?

Wenn ich versuche, das erstere zu verwenden, das 08 Das Formatierungsflag wurde entfernt, und es funktioniert nicht mit just 8.

  • Meinst du 0x%.8X ? Dass Wille Lead-Fill mit Nullen. (das 0x ist nur eine Präambel, aber das ist Ihnen wahrscheinlich bereits bewusst).

    – WhozCraig

    6. Februar 2013 um 16:23 Uhr


Mikes Benutzeravatar
Mike

Das # Teil gibt Ihnen a 0x in der Ausgabezeichenfolge. Das 0 und die x Zählen Sie gegen Ihre “8” Zeichen, die in der aufgelistet sind 08 Teil. Sie müssen nach 10 Zeichen fragen, wenn Sie möchten, dass es gleich ist.

int i = 7;

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

Auch den Fall ändern xwirkt sich auf die Schreibweise der ausgegebenen Zeichen aus.

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

  • Die oberste Zeile gibt für mich 14F0x00000007 aus. Das zweite und dritte Werk wie geschrieben.

    – Quantenkartoffel

    6. Januar 2014 um 3:15 Uhr

  • @quantumpotato – Das ist … seltsam. Die erste und die dritte Zeile sind identisch mit Ausnahme der Anzahl von Nullen, die sie erzeugen sollten. Was war Ihr Compiler / System / Codezeile, die dies erzeugt hat? Hatten Sie Zeilen vor der gedruckten? 14F?

    – Mike

    8. Januar 2014 um 14:23 Uhr

  • Beachten Sie, dass wenn i = 0;die Versionen mit %# wird die nicht enthalten 0x Präfix.

    – Jonathan Leffler

    19. November 2014 um 8:13 Uhr

  • aber wie wäre es mit dem Hex: 0x43A66C31C68491C0 Ich habe folgendes versucht: __int64 int64 = 0x43A66C31C68491C0; printf_s(“%#15X %d”,int64,int64); Aber die Ausgabe ist 0XC68491C0, nicht 0x43A66C31C68491C0

    – 123iamking

    7. Mai 2016 um 4:16 Uhr


  • Über das Hex 0x43A66C31C68491C0 oben habe ich es gelöst, die Lösung ist 0x%I64X , nicht %#15X

    – 123iamking

    7. Mai 2016 um 4:30 Uhr

Das „0x“ zählt zu den acht Zeichen. Du brauchst "%#010x".

Beachten Sie, dass # tut nicht hängen Sie das 0x an 0 an – das Ergebnis wird sein 0000000000 – also solltest du wahrscheinlich eigentlich nur verwenden "0x%08x" ohnehin.

  • Danke für den Hinweis # stellt “0x” nicht “0” voran!

    – Jack Humphries

    11. Oktober 2020 um 22:18 Uhr

Benutzeravatar von Jonathan Leffler
Jonathan Leffler

Das %#08X Konvertierung muss dem Wert mit vorangestellt werden 0X; das wird von der Norm gefordert. Es gibt keinen Hinweis in der Norm, dass die # sollte das Verhalten der ändern 08 Teil der Spezifikation, außer dass die 0X Präfix wird als Teil der Länge gezählt (also möchten/müssen Sie vielleicht verwenden %#010X. Wenn Sie, wie ich, Ihr Hex als dargestellt mögen 0x1234CDEFdann müssen Sie verwenden 0x%08X um das gewünschte Ergebnis zu erzielen. Du könntest benutzen %#.8X 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 Maschine, und auch auf Mac OS X v10.7.5 (Löwe), die Ausgabe war:

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 etwas überrascht über die Behandlung von 0; Mir ist nicht klar, warum die 0X Präfix wird weggelassen, aber wenn zwei separate Systeme dies tun, muss es Standard sein. Es bestätigt meine Vorurteile gegenüber dem # Möglichkeit.


Die Behandlung von Null entspricht dem Standard.

ISO/IEC 9899:2011 §7.21.6.1 Das fprintf Funktion

¶6 Die Flaggenzeichen und ihre Bedeutung sind: …
# Das Ergebnis wird in eine “alternative Form” umgewandelt. … Zum x (oder X) Umwandlung, a ungleich Null Ergebnis hat 0x (oder 0X) vorangestellt. …

(Betonung hinzugefügt.)


Beachten Sie, dass mit %#X verwendet Großbuchstaben für die Hexadezimalziffern und 0X als Präfix; verwenden %#x verwendet Kleinbuchstaben für die Hexadezimalziffern und 0x als Präfix. Wenn Sie es vorziehen 0x B. Präfix und Großbuchstaben, müssen Sie codieren 0x separat: 0x%X. Andere Formatmodifikatoren können natürlich nach Bedarf hinzugefügt werden.

Verwenden Sie zum Drucken von Adressen die <inttypes.h> Kopfzeile und die uintptr_t Typ und die PRIXPTR Makro formatieren:

#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 gut für Adressen auf einem Mac mit macOS funktioniert. Kombiniert mit der . Um die Mindestgenauigkeit (Ziffern) anzugeben, werden Adressen zuverlässig formatiert. Wenn Sie die Genauigkeit auf 16 setzen, sind die zusätzlichen 4 Ziffern meiner Erfahrung nach auf dem Mac immer 0, aber es gibt sicherlich Gründe dafür, 16 statt 12 in portablem 64-Bit-Code zu verwenden (aber Sie würden 8 für verwenden 32-Bit-Code).

Benutzeravatar von chqrlie
chqrlie

# verursacht 0x (oder 0X zum %#X) der Ausgabe vorangestellt werden, es sei denn, der Wert ist 0sollten Sie also nicht verwenden # falls Sie es wollen 0x immer in der Ausgabe erscheinen.

Sie können das Breitenfeld in Kombination mit verwenden 0 Flag, um führende Nullen zu erzeugen: %08x füllt die Zahl mit führenden Nullen auf eine Breite von auf 8. Wenn Sie eine konsistente Ausgabe für alle 32-Bit-Werte wünschen, verwenden Sie "0x08x".

Sie können auch das Präzisionsfeld verwenden: %.8x füllt die Zahl mit führenden Nullen zu einer Summe von auf 8 Ziffern. Daher können Sie auch verwenden "0x%.8x" für Ihren Zweck.

Diese Konvertierungsspezifikationen würden sich unterscheiden, wenn im Rahmen der Konvertierung ein Präfix generiert wird, z 0x zum # oder - für negative Zahlen in vorzeichenbehafteten Konvertierungen, deren Länge für die Breite, aber nicht für den Genauigkeitsbezeichner gezählt wird. Außerdem kann das Präzisionsfeld mit dem Breitenfeld kombiniert werden:

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|

Ich würde empfehlen, das letzte zu verwenden: "0x%.8x".

Benutzeravatar von Stephan Gheorghica
Stephan Gheorgica

Sie können immer “%p” verwenden, um 8-Bit-Hexadezimalzahlen anzuzeigen.

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

Ausgabe:

0xf0000000

  • Welche Umgebung definiert uint8_t und uint32_t?

    – Peter Mortensen

    26. April 2021 um 12:31 Uhr

  • Angefangen mit #include <stdio.h> und #include <stdint.h> kann ausreichend sein.

    – Peter Mortensen

    26. April 2021 um 13:29 Uhr

  • Mit diesem Inhalt, unter Linux, gcc -x c Hexprint_p.c ergibt sich warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘uint32_t’ {aka ‘unsigned int’} [-Wformat=].

    – Peter Mortensen

    26. April 2021 um 13:30 Uhr

  • Die Ausgabe von %p ist implementierungsabhängig und besteht eine int32_t zum %p hat undefiniertes Verhalten. Definitiv keine gute Lösung.

    – chqrlie

    27. April 2021 um 9:54 Uhr

  • Funktioniert in meiner Umsetzung einwandfrei! Das Ergebnis ist jedoch Stamm links für Nullen (printf("Sl_1: %p\n", 0x0123) => Sl_1: 0x123)

    – tontonCD

    27. März um 16:20 Uhr


  • Welche Umgebung definiert uint8_t und uint32_t?

    – Peter Mortensen

    26. April 2021 um 12:31 Uhr

  • Angefangen mit #include <stdio.h> und #include <stdint.h> kann ausreichend sein.

    – Peter Mortensen

    26. April 2021 um 13:29 Uhr

  • Mit diesem Inhalt, unter Linux, gcc -x c Hexprint_p.c ergibt sich warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘uint32_t’ {aka ‘unsigned int’} [-Wformat=].

    – Peter Mortensen

    26. April 2021 um 13:30 Uhr

  • Die Ausgabe von %p ist implementierungsabhängig und besteht eine int32_t zum %p hat undefiniertes Verhalten. Definitiv keine gute Lösung.

    – chqrlie

    27. April 2021 um 9:54 Uhr

  • Funktioniert in meiner Umsetzung einwandfrei! Das Ergebnis ist jedoch Stamm links für Nullen (printf("Sl_1: %p\n", 0x0123) => Sl_1: 0x123)

    – tontonCD

    27. März um 16:20 Uhr


1426280cookie-checkprintf() Formatierung für hexadezimal

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy