scanf ("% [^ \ n] s", a) vs bekommt (a)

8

Mir wurde gesagt, dass scanf nicht verwendet werden sollte, wenn der Benutzer eine Zeichenfolge eingibt. Gehen Sie statt dessen auf gets () von den meisten Experten und auch den Benutzern von StackOverflow. Ich habe es auf StackOverflow nie gefragt, warum man scanf nicht für Strings verwenden sollte. Dies ist nicht die eigentliche Frage, aber die Antwort auf diese Frage wird sehr geschätzt.

Kommen wir nun zur eigentlichen Frage. Ich bin auf diese Art von Code gestoßen -

%Vor%

Dies liest eine Zeichenfolge, bis der Benutzer ein neues Zeilenzeichen eingibt, wobei die Leerstellen auch als Zeichenfolge betrachtet werden.

Gibt es ein Problem, wenn ich

verwende? %Vor%

statt bekommt?

Wird mehr optimiert als scanf-Funktion, wie es klingt, wird gets rein für die Handhabung von Strings gewidmet. Bitte lass es mich wissen.

Aktualisieren

Dieser Link hat mir geholfen, es besser zu verstehen.

    
niko 18.11.2011, 04:23
quelle

2 Antworten

7

gets(3) ist gefährlich und sollte um jeden Preis vermieden werden. Ich kann mir keinen Gebrauch vorstellen, wo gets(3) nicht eine Sicherheitslücke ist.

scanf(3) s %s ist ebenfalls gefährlich - Sie müssen den Spezifizierer "Feldbreite" verwenden, um die Größe des von Ihnen zugewiesenen Puffers anzuzeigen. Ohne die Feldbreite ist diese Routine so gefährlich wie gets(3) :

%Vor%

Die GNU C-Bibliothek stellt den a Modifikator für %s zur Verfügung, der den Puffer für Sie zuweist. Diese nicht-portable Erweiterung ist wahrscheinlich weniger schwierig zu verwenden:

%Vor%     
sarnold 18.11.2011, 04:39
quelle
3

Erstens ist es nicht klar, was% code_% in Ihrer Formatzeichenfolge tut. Der s -Teil ist ein autarker Formatbezeichner. Es ist kein Modifikator für %[^\n] format, wie Sie zu glauben scheinen. Dies bedeutet, dass %s format string von "%[^\n]s" als zwei unabhängige Formatbezeichner interpretiert wird: scanf gefolgt von einem einzelnen %[^\n] . Dadurch wird s angewiesen, alles zu lesen, bis scanf angetroffen wird (wobei \n ungelesen bleibt), und dann muss das nächste Eingabezeichen \n sein. Das macht einfach keinen Sinn. Keine Eingabe passt zu einem solchen widersprüchlichen Format.

Zweitens, was anscheinend gemeint war, ist s . Das liegt etwas nahe bei [nicht mehr verfügbar] scanf("%[^\n]", a) (oder gets ), aber es ist nicht dasselbe. fgets erfordert, dass jeder Formatbezeichner mit mindestens einem Eingabezeichen übereinstimmt. scanf wird fehlschlagen und abbrechen, wenn keine Eingabezeichen für den angeforderten Formatbezeichner gefunden werden können. Dies bedeutet, dass scanf nicht in der Lage ist, leere Eingabezeilen, d. H. Zeilen, die scanf("%[^\n]",a) -Zeichen enthalten, sofort zu lesen. Wenn Sie eine solche Zeile in das obige \n einspeisen, wird scanf zurückgegeben, um einen Fehler anzuzeigen und 0 unverändert zu belassen. Das ist ganz anders als typische zeilenbasierte Eingabefunktionen.

(Das ist ziemlich überraschend und scheinbar unlogisch von a format. Persönlich würde ich %[] bevorzugen, um leere Sequenzen abzugleichen und leere Strings zu erzeugen, aber das ist nicht wie Standard %[] funktioniert. )

Wenn Sie die Eingabe Zeile für Zeile lesen möchten, ist scanf die beste Option.

    
AnT 10.11.2016 20:59
quelle

Tags und Links