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 scanf
wurde 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 char
Als 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 wird0x
und oktal, wenn vorangestellt0
. Zum Beispiel die Zeichenfolge031
würde als 31 mit gelesen werden%d
und 25 mit%i
. Die Flaggeh
im%hi
zeigt die Umwandlung in a anshort
undhh
Umwandlung in achar
.%u
: Nach Dezimalstellen suchenunsigned 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 Wertstrtoul()
.[failed verification]) Entsprechend%hu
scannt nach einemunsigned short
und%hhu
für einunsigned 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]
Recent Comments