Wie klar stdin, bevor man neuen input?
Ich gelesen habe, etwa 5-10 verschiedene Vorschläge, wie klar stdin, aber keiner von Ihnen passt meine Bedürfnisse. Die Sache ist, dass fflush(stdin)
funktionierte perfekt auf meinem Rechner, aber leider scheint es nicht überall arbeiten, also brauche ich etwas mit den gleichen Funktionen. Jeder andere Weg habe ich versucht löscht stdin, wenn es nicht leer ist, sondern die Benutzereingabe erfordert, wenn stdin IST leer, was bedeutet, es erfordert die Eingabe in einem moment, den ich nicht wollen, zu bekommen (+ verwirft er es sowieso).
Ist die Frage: Kann ich irgendwie sicherstellen, dass stdin
leer IST, bevor ich eine Benutzereingabe erforderlich ist? (und wenn nicht, DANN, und nur dann ist es klar, irgendwie?)
so etwas wie:
if (stdin is NOT empty)
while (getchar() != '\n')
continue;
EDIT: die Sache ist, dass ich ein load-Zeichen aus stdin
eins nach dem anderen und irgendwann, ein Teil der Eingaben aus der vorherigen iteration möglicherweise oder möglicherweise nicht bekommen verworfen. so oder so, muss ich haben klar stdin
bevor ich den Benutzer auffordern, für einen anderen Eingang verarbeitet werden. Löschen der Puffer selbst ist nicht so eine große Sache, das problem ist, was passiert, wenn die Eingabe leer ist, wenn das Programm auf den Punkt clearing stdin
, denn in diesem moment muss das Programm eine weitere Eingabe, die gehen, um gegessen zu werden durch die clearing-Funktion. Das ist, was ich loswerden will. (wenn ich könnte fflush(stdin);
ich wusste nur, dass die nächste Zeile des Programms die stdin
leer, egal was, keine Frage...)
fflush(stdin)
ist UB.- Es gibt keine solche Sache wie eine leere I/O-stream , es ist ein stream. Bedenken Sie:
./myprog </dev/random
; wird es jemals sehen das Ende seiner stdin-stream? - Programmierung unter windows, hat die Arbeit an linux...
- Nur, welche Art von app möchten Sie dies tun? In 30 Jahren C-Programmierung habe ich nie die Notwendigkeit verspürt, und ich kenne absolut keine Programm, dies zu tun. Aber alle Neulinge wollen es. warum, OH WARUM? Was ist die anti-pattern? Was ist der XY-problem, das Sie lösen möchten?
- Wollen Sie flush teilweise typisierte Zeilen von Eingabe (d.h. die Eingabe, für die der Anwender noch nicht eingegeben GEBEN Sie zu Begehen) als gut?
- Die
apt-get
Programm tut dies absichtlich. Siehe Verhindern, dass sudo, apt-get, etc. schlucken eingefügt input auf STDIN
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mit Tragbarer C ist dies nicht möglich.
Stattdessen vorschlagen, eine andere (und üblichere C) Paradigma:
Versichern vorherigen input-Funktionen verbraucht alle der vorherigen Eingabe.
fgets()
(oder *nixgetline()
) ist der typische Ansatz und löst die meisten Situationen.Oder Rollen Sie Ihre eigenen. Das folgende liest eine ganze Zeile, aber nicht speichern zusätzliche Eingabe.
TL;DR
fflush(stdin)
ruft Undefiniertes Verhalten nach der standard, sollten Sie nie benutzen.Kommen, um Ihren code (Logik), statt der Suche nach einem newline, kann man sich
EOF
. Es muss nicht eine Voraussetzung, dassstdin
sollte einige Eingabe vor der Ausführung dieser Schleife.Etwas wie
sollte Ihren Bedürfnissen entsprechen.
^D
oder^Z
), während der OP fragte nach einem Weg, Spülen Sie den input-buffer.Verwenden nur
fgets()
zu Lesenstdin
.Verwenden Sie einen ausreichend großen Puffer und/oder test für volle Linien.
Mit
fgets()
Sie müssen sich nie sorgen zu machen über die zusätzlichen Zeichen instdin
.if (tmp[strlen(tmp) - 1] != '\n')
ist UB, wenntmp[0] == 0
. Leicht genug, um das erste Zeichen zu Lesen, die vonfgets()
zu sein, die null-Zeichen.stdin
, Tastatur, ...) nicht haben embedded-NULs. Code geändert, damit umzugehen sowieso. Dank'\0'
. Doch es ist nicht selten, entweder zum Lesen einer UTF-16BE text - Datei fehlt eine BOM (denken, es ist eine einfache ASCII -) Datei, die kann leicht zu einem führenden null-Zeichen. Wenn eine Tastatur erzeugen kann, die ein null-Zeichen ist oder nicht, ist ein Plattform-Niveau-Problem, über das Programm gesteuert werden. IMO ist es ein hacker ausnutzen und robusten code meistert. bis Abstimmung für bessere Antwort.Den
select
Modul bietet eine Funktion namensselect
erreicht genau das, was du bist suchen für.select.select
nimmt drei Argumente:Jedes argument sollte sein, eine Liste von Datei-Deskriptoren (wie
[sys.sdtin]
) und dann wartet, bis eine bestimmte IO-Betrieb verfügbar ist. Der IO-Operationen sind read, wRitus oder eine andere exAusnahme auf die Datei-Deskriptoren. Es gibt einetuple
von entsprechenden Listen gefüllt mit den Datei-Deskriptoren, die bereit sind.Also, wenn es Eingang warten in
sys.stdin
dann wäre die Funktion Verhalten sich etwa so:Durch sich selbst, dies nicht Ihr problem lösen, da standardmäßig die Funktion wartet, bis ein E /a-Betrieb verfügbar ist. Wichtig aber ist, dass
select.select
hat eine optionaletimeout
argument, die angibt, wie lange es warten soll, bevor aufgegeben wird. Wir müssen einfach setzen Sie das timeout auf null, und wir können überprüfen für die Eingabe, ohne zu blockieren den Programmablauf.Lassen Sie uns sehen, ein Beispiel, wo es ist keine Eingabe einer Wartezeit in
sys.stdin
:Wissen, dass wir nur das erste element der Tupel (der input-streams), die wir bereit sind, um eine sinnvolle if-Anweisung:
Das bedeutet, dass die clearing-input-stream braucht nur einige iteration:
Und natürlich können wir dies auf beliebige input-Streams, so können steckte es in eine Funktion:
Also lasst uns demonstrieren, unsere Funktion zu erreichen, was Sie Fragen in Ihrer Frage:
Den
clear_input
Funktion kann verwendet werden, als eine nicht-blockierende Art und Weise zu klare input-streams und sollte in Python2 und Python ist3.