Wie lösche ich die Standardeingabe, bevor ich eine neue Eingabe erhalte?

8

Ich habe ungefähr 5-10 verschiedene Ratschläge gelesen, wie man die Standardversion löscht, aber keine von ihnen passt zu meinen Bedürfnissen. Die Sache ist, dass fflush(stdin) perfekt an meinem Computer funktioniert, aber leider scheint es nicht überall zu funktionieren, also brauche ich etwas mit der gleichen Funktionalität. Jede andere Art, die ich versuchte, löscht Stdin, wenn es nicht leer ist, aber erfordert Benutzereingaben, wenn stdin leer ist, was bedeutet, dass es Eingaben in einem Moment benötigt, den ich nicht bekommen möchte (+ es verwirft es trotzdem).

Die Frage ist: Kann ich irgendwie sicherstellen, dass stdin leer ist, bevor ich Benutzereingaben benötige? (und wenn nicht, dann und nur dann löschen Sie es irgendwie?) etwas wie:

%Vor%

BEARBEITEN: Die Sache ist, dass ich Zeichen von stdin eins nach dem anderen lade und irgendwann ein Teil der Eingabe von der vorherigen Iteration vielleicht weggeworfen wird oder nicht. So oder so, ich muss clear stdin haben, bevor ich den Benutzer nach einer anderen Eingabe frage, die bearbeitet werden soll. Das Löschen des Puffers selbst ist keine so große Sache, das Problem ist, was passiert, wenn die Eingabe leer ist, wenn das Programm zum Löschen von stdin kommt, weil das Programm in diesem Moment eine andere Eingabe benötigt, die aufgefressen werden soll die Clearing-Funktion. Das will ich loswerden. (Wenn ich fflush(stdin); benutzen konnte, wusste ich einfach, dass für die nächste Zeile meines Programms stdin leer ist, egal was, keine Fragen ...)

    
Tom 19.04.2016, 09:58
quelle

4 Antworten

2
  

Wie lösche ich die Standardeingabe, bevor ich eine neue Eingabe erhalte?
  .. also brauche ich etwas mit der gleichen Funktionalität.

Mit Portable C ist das nicht möglich.

Stattdessen schlagen Sie ein anderes (und üblicheres C) Paradigma vor: Stellen Sie sicher, dass vorherige Eingabefunktionen alle die vorherige Eingabe verwenden.

fgets() (oder * nix getline() ) ist der typische Ansatz und löst die meisten Situationen.

Oder rollen Sie Ihre eigenen. Folgendes verbraucht, speichert jedoch keine zusätzlichen Eingaben.

%Vor%     
chux 19.04.2016 15:35
quelle
1

TL; DR fflush(stdin) ruft undefiniertes Verhalten gemäß dem Standard auf, das sollten Sie benutze es nie.

Kommen Sie zu Ihrem Code (Logik), anstatt nach einer neuen Zeile zu suchen, können Sie nach EOF suchen. Es ist nicht erforderlich, dass stdin vor dem Ausführen dieser Schleife einige -Eingaben haben sollte.

Etwas wie

%Vor%

sollte Ihren Bedürfnissen entsprechen.

    
Sourav Ghosh 19.04.2016 10:01
quelle
1

Verwenden Sie nur fgets() , um stdin zu lesen.

Verwenden Sie einen Puffer, der groß genug ist und / oder testen Sie ihn auf volle Zeilen.

Mit fgets() musst du dich nie um zusätzliche Zeichen in stdin kümmern.

%Vor% %Vor%     
pmg 19.04.2016 11:19
quelle
-1

Das Modul select bietet eine Funktion namens select , die genau das liefert, wonach Sie suchen. select.select benötigt drei Argumente:

%Vor%

Jedes Argument sollte eine Liste von Dateideskriptoren sein (z. B. [sys.sdtin] ) und wartet dann, bis eine bestimmte IO-Operation verfügbar ist. Die IO-Operationen sind r ead, w rite oder einige andere x Einstellungen für die angegebenen Dateideskriptoren. Sie gibt tuple der entsprechenden Listen zurück, die mit den bereitstehenden Dateideskriptoren gefüllt sind.

Wenn also die Eingabe in sys.stdin wartet, verhält sich die Funktion wie folgt:

%Vor%

Dies löst Ihr Problem nicht, da die Funktion standardmäßig wartet, bis eine IO-Operation verfügbar ist. Wichtig ist jedoch, dass select.select ein optionales Argument timeout hat, das angibt, wie lange es warten soll, bis es aufgibt. Wir müssen das Timeout einfach auf Null setzen und können nach Eingaben suchen, ohne den Programmfluss zu blockieren.

Sehen wir uns ein Beispiel an, in dem keine Eingabe in sys.stdin wartet:

%Vor%

Da wir wissen, dass wir nur das erste Element dieses Tupels (die Eingabeströme) wollen, sind wir bereit, eine nützliche if-Anweisung zu erstellen:

%Vor%

Das bedeutet, dass das Löschen des Eingabestreams nur einige Iterationen erfordert:

%Vor%

Und wir können das natürlich für jeden Eingabestream verwenden, also lassen Sie es in eine Funktion einfügen:

%Vor%

Lassen Sie uns also unsere Funktion demonstrieren, um das zu erreichen, wonach Sie in Ihrer Frage fragen:

%Vor%

Die Funktion clear_input kann als nicht blockierende Methode zum Löschen von Eingabeströmen verwendet werden und sollte in Python2 und Python3 funktionieren.

    
dsclose 19.04.2016 12:36
quelle

Tags und Links