Scanf-Format-Zeichenfolge – Wikipedia

EIN Scanf-Format-Zeichenfolge ((scannen formatted) ist ein Steuerparameter, der in verschiedenen Funktionen verwendet wird, um das Layout einer Eingabezeichenfolge festzulegen. Die Funktionen können dann die Zeichenfolge teilen und in Werte geeigneter Datentypen übersetzen. Funktionen zum Scannen von Zeichenfolgen werden häufig in Standardbibliotheken bereitgestellt.

Der Begriff “scanf” stammt aus der C-Bibliothek, die diese Art von Funktion populär gemacht hat, aber solche Funktionen sind älter als C, und andere Namen werden verwendet, wie z readf in ALGOL 68. Zeichenfolgen im Scanf-Format, die formatierte Eingaben (Parsing) bereitstellen, ergänzen Zeichenfolgen im Printf-Format, die formatierte Ausgaben (Vorlagen) bereitstellen. Diese bieten im Vergleich zu anspruchsvolleren und flexibleren Parsern oder Template-Engines einfache Funktionen und ein festes Format, sind jedoch für viele Zwecke ausreichend.

Geschichte[edit]

Die tragbare Eingabe- / Ausgabebibliothek von Mike Lesk, einschließlich scanfwurde offiziell Teil von Unix in Version 7.[1]

Das scanf Die in C enthaltene Funktion liest Eingaben für Zahlen und andere Datentypen aus der Standardeingabe (häufig eine Befehlszeilenschnittstelle oder eine ähnliche Art von Textbenutzeroberfläche).

Der folgende C-Code liest eine variable Anzahl unformatierter Dezimalzahlen aus dem Standardeingabestream und druckt jede in separaten Zeilen aus:

#include 

int main(void)
{
    int n;

    while (scanf("%d", &n) == 1)
        printf("%dn", n);
    return 0;
}

Nach der Verarbeitung durch das obige Programm wird eine unregelmäßig verteilte Liste von Ganzzahlen wie z

456 123 789 456 12
456 1
      2378

wird in konsistenten Abständen angezeigt als:

456
123
789
456
12
456
1
2378

So drucken Sie ein Wort aus:

#include 

int main(void)
{
    char word[20];

    if (scanf("%19s", word) == 1)
        puts(word);
    return 0;
}

Unabhängig vom Datentyp, den der Programmierer vom Programm lesen lassen möchte, werden die Argumente (z &n oben) müssen Zeiger sein, die auf den Speicher zeigen. Andernfalls wird die Funktion nicht korrekt ausgeführt, da versucht wird, die falschen Speicherbereiche zu überschreiben, anstatt auf den Speicherort der Variablen zu zeigen, für die Sie eine Eingabe erhalten möchten.

Im letzten Beispiel eine Adresse des Operators (&) ist nicht für das Argument verwendet: as word ist der Name eines Arrays von charAls solches entspricht es (in allen Kontexten, in denen es eine Adresse ergibt) einem Zeiger auf das erste Element des Arrays. Während der Ausdruck &word würde numerisch auf den gleichen Wert ausgewertet, semantisch hat es eine ganz andere Bedeutung, da es eher für die Adresse des gesamten Arrays als für ein Element davon steht. Diese Tatsache muss bei der Zuweisung berücksichtigt werden scanf Ausgabe an Strings.

Wie scanf Viele Programmiersprachen mit Schnittstellen wie PHP haben Ableitungen wie sscanf und fscanf aber nicht scanf selbst.

Formatieren Sie die Zeichenfolgenspezifikationen[edit]

Die Formatierungsplatzhalter in scanf sind mehr oder weniger gleich wie in printf, seine umgekehrte Funktion. Wie in printf die POSIX-Erweiterung n$ ist definiert.[2]

Es gibt selten Konstanten (dh Zeichen, die keine Platzhalter formatieren) in einer Formatzeichenfolge, hauptsächlich weil ein Programm normalerweise nicht zum Lesen bekannter Daten ausgelegt ist scanf akzeptiert diese, wenn ausdrücklich angegeben. Die Ausnahme sind ein oder mehrere Leerzeichen, wodurch alle Leerzeichen in der Eingabe verworfen werden.[2]

Einige der am häufigsten verwendeten Platzhalter folgen:

  • %a : Scannen Sie eine Gleitkommazahl in hexadezimaler Schreibweise.
  • %d : Scannen Sie eine Ganzzahl als vorzeichenbehaftete Dezimalzahl.
  • %i : Scannen Sie eine Ganzzahl als vorzeichenbehaftete Zahl. Ähnlich zu %d, interpretiert die Zahl jedoch als hexadezimal, wenn vorangestellt wird 0x und oktal, wenn vorangestellt 0. Zum Beispiel die Zeichenfolge 031 würde als 31 mit gelesen werden %dund 25 mit %i. Die Flagge h im %hi zeigt die Umwandlung in a an short und hh Umwandlung in a char.
  • %u : Nach Dezimalstellen suchen unsigned int (Beachten Sie, dass im C99-Standard das Minuszeichen für den Eingabewert optional ist. Wenn also ein Minuszeichen gelesen wird, treten keine Fehler auf und das Ergebnis ist das Zweierkomplement einer negativen Zahl, wahrscheinlich ein sehr großer Wert strtoul().[failed verification]) Entsprechend %hu scannt nach einem unsigned short und %hhu für ein unsigned char.
  • %f : Scannen Sie eine Gleitkommazahl in normaler (Festkomma-) Notation.
  • %g, %G : Scannen Sie eine Gleitkommazahl in normaler oder exponentieller Notation. %g verwendet Kleinbuchstaben und %G verwendet Großbuchstaben.
  • %x, %X : Scannen Sie eine Ganzzahl als vorzeichenlose Hexadezimalzahl.
  • %o : Scannen Sie eine Ganzzahl als Oktalzahl.
  • %s : Scannen Sie eine Zeichenfolge. Der Scan wird mit Leerzeichen beendet. Am Ende der Zeichenfolge wird ein Nullzeichen gespeichert. Dies bedeutet, dass der bereitgestellte Puffer mindestens ein Zeichen länger als die angegebene Eingabelänge sein muss.
  • %c : Scannen Sie ein Zeichen (char). Es wird kein Nullzeichen hinzugefügt.
  • Leerzeichen: Alle Leerzeichen lösen einen Scan nach null oder mehr Leerzeichen aus. Die Anzahl und der Typ der Leerzeichen müssen in keiner Richtung übereinstimmen.
  • %lf : Als doppelte Gleitkommazahl scannen. “Float” -Format mit dem “langen” Bezeichner.
  • %Lf : Als lange doppelte Gleitkommazahl scannen. “Float” formatiert den “long long” -Spezifizierer.
  • %n ::

Das Obige kann in Verbindung mit numerischen Modifikatoren und dem verwendet werden l, L Modifikatoren, die für “lang” und “lang lang” zwischen dem Prozentzeichen und dem Buchstaben stehen. Es können auch numerische Werte zwischen dem Prozentzeichen und den Buchstaben vor dem stehen long ggf. Modifikatoren, die die Anzahl der zu scannenden Zeichen angeben. Ein optionales Sternchen (*) direkt nach dem Prozentzeichen bedeutet, dass das von diesem Formatbezeichner gelesene Datum nicht in einer Variablen gespeichert werden soll. Für diese abgelegte Variable sollte kein Argument hinter der Formatzeichenfolge enthalten sein.

Das ff Der Modifikator in printf ist in scanf nicht vorhanden, was zu Unterschieden zwischen den Ein- und Ausgabemodi führt. Das ll und hh Modifikatoren sind im C90-Standard nicht vorhanden, aber im C99-Standard.[3]

Ein Beispiel für eine Formatzeichenfolge ist

"%7d%s %c%lf"

Die obige Formatzeichenfolge scannt die ersten sieben Zeichen als Dezimalzahl, liest dann die verbleibenden Zeichenfolgen als Zeichenfolge, bis ein Leerzeichen, eine neue Zeile oder eine Registerkarte gefunden wird, verbraucht dann Leerzeichen, bis das erste Nicht-Leerzeichen gefunden wird, und verbraucht dann dieses Zeichen. und scannt schließlich die verbleibenden Zeichen als Doppel. Daher muss ein robustes Programm prüfen, ob die scanf Anruf erfolgreich und entsprechende Maßnahmen ergreifen. Wenn die Eingabe nicht das richtige Format hatte, befinden sich die fehlerhaften Daten weiterhin im Eingabestream und müssen verworfen werden, bevor neue Eingaben gelesen werden können. Eine alternative Methode, die dies vermeidet, ist die Verwendung fgets und überprüfen Sie dann die eingelesene Zeichenfolge. Der letzte Schritt kann von ausgeführt werden sscanf, zum Beispiel.

Im Fall der vielen Float-Zeichen a, e, f, gViele Implementierungen entscheiden sich dafür, die meisten in denselben Parser zu reduzieren. Microsoft MSVCRT macht es mit e, f, g,[4] während glibc dies mit allen vier tut.[2]

Sicherheitslücken[edit]

scanf ist anfällig für Formatierungs-String-Angriffe. Es sollte sorgfältig darauf geachtet werden, dass die Formatierungszeichenfolge Einschränkungen für die Zeichenfolgen- und Arraygröße enthält. In den meisten Fällen ist die Größe der Eingabezeichenfolge eines Benutzers beliebig und kann nicht vor dem festgelegt werden scanf Funktion wird ausgeführt. Dies bedeutet, dass Verwendungen von %s Platzhalter ohne Längenangaben sind von Natur aus unsicher und können für Pufferüberläufe ausgenutzt werden. Ein weiteres potenzielles Problem besteht darin, dynamische Formatierungszeichenfolgen zuzulassen, z. B. Formatierungszeichenfolgen, die in Konfigurationsdateien oder anderen benutzergesteuerten Dateien gespeichert sind. In diesem Fall kann die zulässige Eingabelänge von Zeichenfolgengrößen nur angegeben werden, wenn die Formatierungszeichenfolge zuvor überprüft und Einschränkungen erzwungen wurden. Im Zusammenhang damit stehen zusätzliche oder nicht übereinstimmende Formatierungsplatzhalter, die nicht mit der tatsächlichen Vararg-Liste übereinstimmen. Diese Platzhalter können teilweise aus dem Stapel extrahiert werden oder unerwünschte oder sogar unsichere Zeiger enthalten, abhängig von der speziellen Implementierung von varargs.

Siehe auch[edit]

Verweise[edit]

Externe Links[edit]