C - Der% x-Formatbezeichner

77

Ich habe eine kleine Frage. Ich weiß, dass der Formatbezeichner% x verwendet werden kann, um Werte aus dem Stapel in einem Formatzeichenfolgenangriff zu lesen.

Ich habe folgenden Code gefunden:

%08x%08x%08x%08x

Was bedeutet die 08? Was macht es genau? Vielen Dank :)

Matthew
quelle
1
Feldbreite von 8 Zeichen, kürzere Zahlen mit vorangestellten Nullen, die der Feldbreite entsprechen, z . B. 000007acoder 0005ceef.
Hristo Iliev
2
Über welche Funktion spricht das? Sie sagen "Werte lesen", aber alle Antworten scheinen davon auszugehen, printf()dass sie verwendet werden.
Entspannen Sie
1
@unwind guter Punkt. wir alle schreiben für printf.
Grijesh Chauhan
1
Wie dumm von mir. Ja, ich habe mich auf die Verwendung dieses Codes innerhalb der printf-Funktion bezogen.
Matthew

Antworten:

138

Nervenzusammenbruch:

  • 8 sagt, dass Sie 8 Ziffern anzeigen möchten
  • 0dass Sie 0's anstelle von nur Leerzeichen voranstellen möchten
  • x dass Sie in hexadezimaler Kleinbuchstabe drucken möchten.

Schnelles Beispiel (danke an Grijesh Chauhan):

#include <stdio.h>
int main() {
    int data = 29;
    printf("%x\n", data);    // just print data
    printf("%0x\n", data);   // just print data ('0' on its own has no effect)
    printf("%8x\n", data);   // print in 8 width and pad with blank spaces
    printf("%08x\n", data);  // print in 8 width and pad with 0's

    return 0;
}

Ausgabe:

1d
1d
      1d
0000001d

Siehe auch http://www.cplusplus.com/reference/cstdio/printf/ als Referenz.

Schallwelle
quelle
9
Es wurde ein Beispiel hinzugefügt, das Ihnen gefällt. WENN nicht, können Sie zu Ihrer Version zurückkehren
Grijesh Chauhan
1
@ Matthew sollten Sie auch mit %-8xund Kapital versuchen X. und beobachten Sie die Wirkung
Grijesh Chauhan
1
Obwohl 8und 0beide Zahlen (und damit identische Teile einer Grammatik in der englischen Sprache) sind, sind sie verschiedene Teile der Grammatik im Printf-Format. 0ist ein "Flag" und 8ist ein Parameter für "width" (was sein kann <ε (no input)>,<d (any number greater than 0)> oder * (a literal asterisk)). Es ist sicher eine nicht intuitive API! Aber was können Sie sagen ... das ist alles altmodisches C-Zeug, bei dem der Speicher so hoch war, dass Sie so viele Zeichen wie möglich in einem Programm speichern möchten - ich stimme ihrer Entscheidung angesichts der Einschränkungen zu, mit denen sie konfrontiert waren!
Ari Sweedler
1
Ich denke jedoch, dass es eine interessante Frage ist, darüber nachzudenken. Wie würden Sie die printfSyntax neu gestalten ? Ich liebe es, %als Escape-Charakter zu verwenden, es ist so einzigartig und eine Nische für die Formatierung von Strings. Ich denke, Modifikatoren sollten jedoch angehängt und nicht vorangestellt werden - auf diese Weise können Sie sie von links nach rechts lesen. So etwas wie %<specifier>[%f<flags>][%-w<width>.<precision>]%statt%[flags][width][.precision][length]specifier . Ich habe %zwischen jedem Feld ein Feld sowie eines zum Schließen ausgewählt (so dass Sie immer noch tun können %x%x- `% x %% x%) und erlaubt einen Multi-Char-Bezeichner
Ari Sweedler
5

%08x bedeutet, dass jede Zahl mindestens 8 Zeichen breit gedruckt werden sollte, wobei alle fehlenden Ziffern mit Nullen gefüllt werden, z. B. für '1' 00000001

Vladimir
quelle
2

Das gibt an, wie viele Ziffern angezeigt werden sollen.

Ganzzahliger Wert oder *, der die minimale Feldbreite angibt. Das Ergebnis wird bei Bedarf (standardmäßig) mit Leerzeichen aufgefüllt, links rechtsbündig oder rechtsbündig linksbündig. Wenn * verwendet wird, wird die Breite durch ein zusätzliches Argument vom Typ int angegeben. Wenn der Wert des Arguments negativ ist, ergibt sich das angegebene Flag und die positive Feldbreite.

Tony der Löwe
quelle
2

Von http://en.wikipedia.org/wiki/Printf_format_string

Verwenden Sie 0 anstelle von Leerzeichen, um ein Feld aufzufüllen, wenn die Option width angegeben ist. Beispielsweise printf("%2d", 3)ergibt sich "3", während printf("%02d", 3)sich "03" ergibt.

David Ranieri
quelle
2

Der von Ihnen erwähnte Formatstring-Angriff auf printf ist nicht spezifisch für die Formatierung "% x". In jedem Fall liest printf mehr Formatierungsparameter als übergebene Variablen und liest Werte aus dem Stapel, die nicht dazu gehören. Sie erhalten das gleiche Problem beispielsweise mit% d. % x ist nützlich, wenn Sie diese Werte als hexadezimal anzeigen möchten.

Wie in den vorherigen Antworten erläutert, erzeugt% 08x eine 8-stellige Hex-Zahl, die durch vorhergehende Nullen aufgefüllt wird.

Verwenden der Formatierung in Ihrem Codebeispiel in printf ohne zusätzliche Parameter:

printf ("%08x %08x %08x %08x");

Ruft 4 Parameter vom Stapel ab und zeigt sie als 8-stellige gepolsterte Hex-Zahlen an.

Ich bin das Walroß
quelle