Warum wird 0 (Null) ohne führendes „0x“ mit dem C-Printf-Format „%#x“ gedruckt?

Lesezeit: 3 Minuten

Benutzer-Avatar
David Poole

Hintergrund: Ich habe eine Reihe von Skripten, die Protokolldateien analysieren, indem sie nach Hex-Zahlen suchen, indem sie das führende “0x” finden. Unsere eingebettete C-Bibliothek wurde auf ein neues printf umgestellt. Das neue printf ist standardkonformer als unser vorheriges und meine Skripte sind kaputt gegangen.

Auf einer Linux-Box:

#include <stdio.h>
int main( void )
{
    printf( "%#010x\n", 0 );
    printf( "%#010x\n", 1 );
    return 0;
}

Ausgabe (mit glibc) ist:

0000000000
0x00000001

Ausgabe auf unserer Firmware war:

0x00000000
0x00000001

Aus printf(3), beim ‘#’-Flag-Zeichen: “Bei x- und X-Konvertierungen wird einem Ergebnis ungleich Null die Zeichenfolge “0x” (oder “0X” für X-Konvertierungen) vorangestellt.”

ich bin neugierig warum. Warum nicht ein führendes 0x für ein Argument mit Nullwert, ohne die C-Standarddokumente zu durchsuchen oder Mittagessen für die Mitglieder des Standardkomitees zu kaufen?

  • Wilde Vermutung: 0 ist 0, unabhängig von der Basis, also muss es nicht angegeben werden.

    – Daniel Fischer

    14. Dezember 2011 um 23:32 Uhr

  • Es ist erwähnenswert, dass Sie das Verhalten von erhalten können stets einschließlich einer führenden 0x durch Schreiben "0x%08x"wohingegen das standardmäßig beschriebene Verhalten schwieriger aus einer Bibliothek zu bekommen wäre stets enthalten die führenden 0x. Vielleicht optimierte das Normenkomitee eher für einen schwer zu erreichenden Fall als für den absolut häufigsten Fall? (Natürlich kann man sich nicht ändern "%#10x" zu "0x%8x"aber andererseits ist es schwer vorstellbar, dass jemand sehen will 0x0 ohne Nullauffüllung.)

    – ruach

    14. Dezember 2011 um 23:36 Uhr

  • Es gibt keine Erwähnung davon in der C89 Begründung (HTML) oder im C99 Begründung (PDF).

    – Keith Thompson

    15. Dezember 2011 um 0:06 Uhr

Benutzer-Avatar
Jukka Suomela

Der Standard scheint so geschrieben zu sein:

  • %#x und %#o versuchen Sie sicherzustellen, dass die Ausgabe korrekt analysiert werden kann, indem Sie verwenden strtol mit base = 0.

  • In diesen Fällen ist die # Flagge fügt hinzu so wenige zusätzliche Zeichen wie möglich. Beispielsweise wird 0 als gedruckt 0 weil es nicht nötig ist, das Extra hinzuzufügen 0x. Dies ist sehr sinnvoll, wenn Sie dies tun nicht Geben Sie die minimale Feldbreite und das Auffüllen mit 0 an.

  • Wenn Sie hinzufügen wollten 0x immer, man könnte oft einfach so etwas schreiben wie 0x%x. Somit %#x scheint nützlich zu sein nur in den speziellen Fällen, in denen Sie wirklich wollen die besondere Behandlung von 0. Aber das Voranstellen von 0x funktioniert nicht gut mit Standard-Feldbreitenbezeichnern, z. B.) 0x%12xwird rechtsbündig durch Leerzeichen zwischen den 0x- und Hex-Ziffern ausgerichtet, was in diesem Fall wahrscheinlich nicht erwünscht ist. Für diesen Fall wäre ein extra Vorbereitungsdurchgang mit sprintf erforderlich, also ein Hex-String wie "0x2ac2" kann mit so etwas wie Leerraum rechtsbündig ausgerichtet werden printf( "%12s", hexstr); Glücklicherweise rechtfertigt mit 0 anstatt Leerzeichen mit so etwas wie printf( "0x%012x", hexstr); funktioniert wie erwartet und erzeugt gültige Hexadezimalziffern für einen Parser.

Nun der Weg %#x spezifiziert ist, um isoliert zu arbeiten, macht viel Sinn. Und so etwas wie %010x spezifiziert ist, um isoliert zu arbeiten, macht viel Sinn. Sie kombinieren diese beiden Modifikatoren, und das Endergebnis ist wohl seltsam. Für eine andere Anwendung, wie das automatische Generieren von sauberem C-Code zum Initialisieren von Tabellen 0, statt 0x0 ist kein Thema.

Aber es muss nicht kombiniert werden %#x und %010x. Du könntest einfach schreiben 0x%08x zu tun, was du willst.

  • Und nachdem ich die Antwort gepostet hatte, bemerkte ich, dass @ruakh bereits in einem Kommentar im Wesentlichen die gleichen Informationen gegeben hatte. Entschuldigung.

    – Jukka Suomela

    15. Dezember 2011 um 0:00 Uhr


  • +1. Es gibt keinen Grund, sich zu entschuldigen. Antworten sind besser als Kommentare. Ich habe meine Gedanken als Kommentar und nicht als Antwort gepostet, weil ich wusste, dass sie nicht vollständig sein können. aber Ihre Antwort ist viel gründlicher und macht viel Sinn.

    – ruach

    15. Dezember 2011 um 0:48 Uhr

  • Sowohl Antworten als auch Kommentare sind willkommen! Die Idee, mit strtol kompatibel zu sein, macht Sinn. Jetzt ist es an der Zeit, dass ich viel Code in 0x%08x ändere.

    – David Poole

    15. Dezember 2011 um 13:42 Uhr

  • Warum nicht 1 hast du auch dieses verhalten? Es ist genauso eindeutig wie 0. Es besteht keine Notwendigkeit, das Extra hinzuzufügen 0x.

    – Burhan Ali

    11. Januar 2013 um 16:59 Uhr

1370390cookie-checkWarum wird 0 (Null) ohne führendes „0x“ mit dem C-Printf-Format „%#x“ gedruckt?

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

Privacy policy