Mit fflush(stdin)
Also eine schnelle Google-Suche für fflush(stdin)
für das löschen des eingabepuffers zeigt zahlreiche websites, die Warnung gegen die Verwendung von es. Und doch, genau wie mein CS-professor unterrichtet die Klasse, es zu tun.
Wie schlimm ist mit fflush(stdin)
? Sollte ich wirklich verzichten, es zu benutzen, auch wenn mein professor ist mit es und es scheint zu funktionieren einwandfrei?
codinghorror.com/blog/2007/03/...
Sowohl Windows und Linux definieren Sie das Verhalten von
Cygwin ist ein Beispiel für eine weit verbreitete Plattform, auf der
Es hängt auch davon ab, was genau Sie erwarten
Sowohl Windows und Linux definieren Sie das Verhalten von
fflush()
auf einen input-stream, und auch definieren, auf die gleiche Weise (Wunder, Wunder). Die POSIX -, C-und C++ - standards für fflush()
definieren Sie nicht das Verhalten, aber keiner von Ihnen verhindern, dass ein system aus, es zu definieren. Wenn Sie die Codierung für maximale Portabilität, vermeiden fflush(stdin)
; wenn Sie Sie Kodieren für Plattformen, bestimmen das Verhalten, verwenden Sie es — aber bewusst sein, dass es nicht tragbar.Cygwin ist ein Beispiel für eine weit verbreitete Plattform, auf der
fflush(stdin);
nicht klar den input.Es hängt auch davon ab, was genau Sie erwarten
fflush(stdin)
zu tun.InformationsquelleAutor wrongusername | 2010-06-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einfach: das ist Undefiniertes Verhalten, da
fflush
soll dazu aufgerufen werden, einen output-stream. Dies ist ein Auszug aus dem C-standard:Es ist also nicht eine Frage von "wie schlimm" das ist.
fflush(stdin)
ist schlicht falsch, und Sie darf nicht nutzen, je.fflush
macht deutlich, es ist gemeint für output-streams direkt im ersten Absatz, die Sie nicht auswendig lernen müssen die C-Norm für, die!Man kann nicht alles wissen. Der Prozessor wird nie wissen, seine Fehler, bis jemand ihm sagt... ich verwendet
fflush(stdin)
für Jahre, bis ich entdeckte, es ist UB (durch einen Unfall)Ich denke Professoren sind auch Menschen 🙂
Äh, sollte es nicht normalerweise konsultieren Sie die Dokumentation zu einer Funktion, bevor Sie es verwenden? Vor allem ein professor?
Ein weiterer Punkt der Verteidigung wäre der folgende Teil der man-Seite (verschiedene glibc-Versionen auf Linux): "Für input-streams,
fflush()
verwirft alle gepufferten Daten, die abgerufen wurde von der zugrunde liegenden Datei, aber wurde nicht von der Anwendung genutzt. Der offene status des Datenstroms ist nicht betroffen." Es ist zwar UB, einige Implementierungen scheinen garantiert, ohne zu erwähnen, seinen status mit Bezug auf den standard.InformationsquelleAutor Eli Bendersky
Konvertierung Kommentare in eine Antwort — und Sie zu erweitern, da das Thema taucht in regelmäßigen Abständen.
Standard-C-und POSIX zu verlassen
fflush(stdin)
als Undefiniertes VerhaltenDen POSIX, C-und C++ - standards für
fflush()
ausdrücklich, dass das Verhalten undefiniert ist, aber keiner von Ihnen verhindern, dass ein system aus, es zu definieren.ISO/IEC 9899:2011 — der C11-Standard — sagt:
POSIX meist verzögert zum C-standard, aber es tut markieren Sie diesen text als eine C-Erweiterung.
Beachten Sie, dass die Klemmen sind nicht in der Lage, zu suchen; weder sind die pipes oder sockets.
Microsoft definiert das Verhalten von
fflush(stdin)
Microsoft und die Visual Studio runtime definiert, die bestimmen das Verhalten von
fflush()
auf einen input-stream.M. M Hinweise:
Dies ist der Grund, warum diese Antwort version meiner Kommentar notes "Microsoft und die Visual Studio runtime' — wenn Sie einen nicht-Microsoft-C-runtime-Bibliothek, die das Verhalten, die Sie sehen, hängt davon ab, dass die Bibliothek.
Linux-Dokumentation und der Praxis scheinen sich zu widersprechen
Überraschend, Linux nominell Dokumente, die das Verhalten von
fflush(stdin)
zu, und auch definiert es die gleiche Art und Weise (Wunder, Wunder).Bleibe ich ein bisschen verwirrt und überrascht an der Linux-Dokumentation zu sagen, dass
fflush(stdin)
arbeiten.Trotz, dass der Vorschlag, es am meisten in der Regel funktioniert nicht auf Linux. Ich habe gerade überprüft die Dokumentation auf Ubuntu 14.04 LTS; es sagt, was oben zitiert, aber empirisch, es funktioniert nicht — zumindest dann, wenn der input-stream ist eine non-seekable device wie ein terminal.
demo-fflush.c
Beispiel für die Ausgabe
Dieser Ausgabe erhalten wurde, die auf beiden Ubuntu 14.04 LTS und Mac OS X 10.11.2. Zu meinem Verständnis, es widerspricht dem, was die Linux-Handbuch sagt. Wenn die
fflush(stdin)
Betrieb arbeitete, würde ich geben Sie eine neue Linie von text, um Informationen für den zweitengetchar()
zu Lesen.Gegeben, was der POSIX-standard sagt, vielleicht eine bessere demonstration gebraucht wird, und die Linux-Dokumentation sollte geklärt werden.
demo-fflush2.c
Beispiel für die Ausgabe
Beachten Sie, dass
/etc/passwd
ist ein seekable file. Auf Ubuntu, die erste Zeile sieht so aus:Auf Mac OS X, die ersten 4 Zeilen so Aussehen:
In anderen Worten, es ist der Kommentar an der Spitze des Mac OS X -
/etc/passwd
- Datei. Die nicht-Kommentar-Zeilen entsprechen, um das normale layout, also dieroot
Eintrag:Ubuntu 14.04 LTS:
Mac-OS-X-10.11.2:
Mac OS X Verhalten ignoriert (oder zumindest scheint Sie zu ignorieren) die
fflush(stdin)
(also nicht nach POSIX zu diesem Thema). Das Linux-Verhalten entspricht den dokumentierten POSIX-Verhalten, aber die POSIX-Spezifikation ist weit vorsichtiger in dem, was es sagt — es gibt eine Datei an, in der Lage zu suchen, sondern terminals, natürlich, nicht zu unterstützen suchen. Es ist auch viel weniger nützlich als die Microsoft-Spezifikation.Zusammenfassung
Microsoft-Dokumente, die das Verhalten von
fflush(stdin)
. Anscheinend funktioniert es, wie beschrieben, auf der Windows-Plattform, unter Verwendung der nativen Windows-compiler und C-runtime-support-Bibliotheken.Trotz Dokumentation im Gegenteil, es funktioniert nicht auf Linux, wenn die Standardeingabe ein terminal, aber es scheint zu Folgen, die POSIX-Spezifikation, die weit mehr ist vorsichtig formuliert. Gemäß dem C-standard, das Verhalten von
fflush(stdin)
ist nicht definiert. POSIX-fügt den qualifier ', es sei denn, die input-Datei ist seekable", die ein terminal nicht. Das Verhalten ist nicht die gleiche wie die von Microsoft.Folglich portable code nicht
fflush(stdin)
. Code, der gebunden ist an die Microsoft-Plattform verwenden und es wird funktionieren, aber Vorsicht der portabilitätsprobleme.POSIX Weise zu entledigen, ungelesen terminal Eingabe aus einem Datei-Deskriptor
Den POSIX-standard-Weg, um Sie zu verwerfen ungelesen-Informationen von einem terminal-file-descriptor (im Gegensatz zu einer stream-Datei wie
stdin
) abgebildet, bei Wie kann ich flush ungelesene Daten aus einer tty input queue auf einem Unix-system. Das ist aber im Betrieb unter standard-I/O-Bibliothek Ebene.InformationsquelleAutor Jonathan Leffler
Laut Norm
fflush
können nur verwendet werden mit dem Ausgabe-Puffer, und offensichtlichstdin
nicht. Allerdings einige Compiler, bietet die Verwendung von fflush(stdin) als Erweiterung. In diesem Fall können Sie es verwenden, aber es wird Auswirkungen auf die Portabilität, so dass Sie nicht mehr in der Lage sein, zu verwenden Standard-konforme compiler auf der Erde und erwarten die gleichen Ergebnisse.InformationsquelleAutor tiftik
Zitat von POSIX:
Beachten Sie, dass terminal ist nicht in der Lage, zu suchen.
InformationsquelleAutor Ryan Chen