Wenn der Code
ist %Vor%vs
%Vor%Was ist der Unterschied? Es scheint, dass beide eine Nachricht erhalten.
Der grundlegende Unterschied [in Bezug auf Ihr spezielles Szenario],
scanf()
beendet die Eingabe, wenn ein whitespace
, newline
oder EOF
gets()
betrachtet ein Leerzeichen als Teil der Eingabezeichenfolge und beendet die Eingabe, wenn newline
oder EOF
gefunden wird.
Um jedoch Pufferüberlauf Fehler zu vermeiden und Sicherheitsrisiken zu vermeiden, ist es sicherer, fgets()
zu verwenden.
Disambiguation: Im folgenden Kontext würde ich " safe " betrachten, wenn es bei richtiger Verwendung nicht zu Problemen führt. Und " unsichere ", wenn die "Unsicherheit" nicht manövriert werden kann.
%Vor%vs
%Vor%Was ist der Unterschied?
In Bezug auf die Sicherheit gibt es keinen Unterschied, beide werden von Standard Input
eingelesen und können sehr wohl message
überlaufen, wenn der Benutzer mehr Daten eingibt als message
Speicher für.
Mit scanf()
können Sie sicher verwendet werden, indem Sie die maximale Anzahl der zu scannenden Daten angeben:
Mit gets()
ist nicht möglich, die maximale Anzahl der einzulesenden Zeichen anzugeben, deshalb sollte das letzte nicht verwendet werden !
Es gibt mehrere. Eine ist, dass gets () nur Zeichenkettendaten erhält. Eine andere ist, dass gets () immer nur eine Variable erhält. scanf () hingegen ist ein viel, viel flexibleres Werkzeug. Es kann mehrere Elemente mit unterschiedlichen Datentypen lesen.
In dem von Ihnen gewählten Beispiel gibt es keinen großen Unterschied.
Der Hauptunterschied besteht darin, dass gets
bis EOF oder \n
liest, während scanf("%s")
liest, bis ein Leerzeichen gefunden wurde. scanf
bietet auch mehr Formatierungsoptionen, hat aber gleichzeitig eine schlechtere Typsicherheit als gets
.
Ein weiterer großer Unterschied ist, dass scanf
eine Standard-C-Funktion ist, während gets
aus der Sprache entfernt wurde, da sie sowohl überflüssig als auch gefährlich war: Es gab keinen Schutz vor Pufferüberläufen. Die gleiche Sicherheitslücke existiert jedoch bei scanf, daher sollte keine dieser beiden Funktionen im Produktionscode verwendet werden .
Sie sollten immer fgets
verwenden, der C-Standard selbst empfiehlt dies sogar, siehe C11 K.3.5.4.1
Empfohlene Vorgehensweise
6 Die fgets-Funktion erlaubt richtig geschrieben Programme, um Eingangszeilen sicher zu verarbeiten, die zu lange im Ergebnis gespeichert werden Array. Im Allgemeinen erfordert dies, dass Anrufer von fgets darauf achten das Vorhandensein oder Fehlen eines neuen Zeilenzeichens im Ergebnis-Array. Ziehen Sie in Erwägung, fgets zu verwenden (zusammen mit allen erforderlichen Verarbeitungsschritten auf Basis von Zeichen für neue Zeilen) anstelle von gets_s.
(Betonung meiner)
erhält: - & gt;
%Vor%FEHLER: - & gt;
%Vor%scanf: - & gt;
%Vor%Fehler
%Vor% Im Fall von scanf
benötigen Sie dieses Format, anders als in gets. Also geben Sie in gets
Buchstaben, Strings, Zahlen und Leerzeichen ein.
Im Fall von scanf
endet die Eingabe, sobald ein Leerraum gefunden wird.
Aber in Ihrem Beispiel verwenden Sie '% s' also weder gets()
noch scanf()
, dass die Zeichenfolgen gültige Zeiger auf Arrays sind, deren Länge ausreicht, um die Zeichen zu speichern, die Sie an sie senden. Daher kann es leicht zu einem Pufferüberlauf kommen.
Tipp: Verwenden Sie fgets()
, aber das hängt vom Anwendungsfall
Das Konzept, dass scanf keinen Leerraum benötigt, ist völlig falsch. Wenn Sie diesen Teil des Codes verwenden, wird auch weißer Leerraum benötigt:
%Vor%Wo die Verwendung der neuen Zeile nur die Eingabe beendet. Das heißt, wenn Sie nur die Eingabetaste drücken, hört die Eingabe auf.
Es gibt also grundsätzlich keinen Unterschied zwischen scanf und bekommt Funktionen. Es ist nur eine knifflige Art der Implementierung.
gets () ist unsicher, zum Beispiel: char str [1]; bekommt (str) Wenn Sie mehr als die Länge eingeben, endet es mit SIGSEGV. Wenn nur gets verwendet werden kann, verwenden Sie malloc als Basisvariable.
scanf()
ist ein viel flexibleres Werkzeug, während gets()
nur eine Variable gleichzeitig erhält.