Eingabepuffer leeren
-
ANSI-C-Benutzer schrieb:
Hallo,
wie kann ich feststellen, ob der Puffer des stdin-Streams (Standardeingabe, gepuffert) leer ist, ohne auf eine Eingabe zu warten ?
Oder wie lässt sich der stdin-Puffer leeren (ohne Eingabe) ?
Vielen Dank im Voraus.Mit freundlichen Grüßen
ANSI-C-Benutzer
Das einzige, wo man sicher sein kann, dass der Puffer leer ist und mir einfällt, ist leider betriebssystemabhängig.
Unter Windows z. B. gibts die Funktion kbhit() mit dieser kann man überprüfen, ob noch ein Zeichen im Tastaturpuffer steht, ohne dass auf eine Eingabe gewartet wird.
-
Und wie wäre damit?
do c = getchar(); while(c!='\0' || c!=EOF);
oder wird \0 nicht eingelesen?
-
supertux schrieb:
Und wie wäre damit?
do c = getchar(); while(c!='\0' || c!=EOF);
oder wird \0 nicht eingelesen?
Das Code-Fragment erzeugt eine Endlosschleife: "c" ist immer ungleich '\0' ODER ungleich EOF.
Du meintest wohl:
do c = getchar(); while(c!='\0' && c!=EOF); /* <== &&: UND-Verknuepfung! */
Aber '\0' wird nur dann erzeugt, wenn der Benutzer Ctrl-@ eingibt, und das nicht vom Betriebssystem abgefangen wird. Bei UNIX wird EOF im Eingabestrom durch Ctrl-D und bei Windows durch Ctrl-Z erzeugt.
Will man bspw. bis zum Zeilenende lesen, sollte man
int c; /* c muss int sein, da EOF meist als -1 definiert ist. */ do c = getchar(); while(c!='\n' && c!=EOF); /* <== '\n': Zeilenende, LF-Character (Ctrl-J) */
-
AJ schrieb:
MG80S schrieb:
Ohne widersprechen zu wollen, eher als alternative Ergänzung:
fflush ( stdin );
Siehe FAQ, warum man das nicht macht!
Oh, das war mir neu. Nunja......danke.
-
@Power: du hast Recht, es muss && statt ||, hab nen Denkfehler beim negieren, denn ¬(a + b) = ¬a · ¬b
Aber ich frage mich immer noch, wie man eine solche Funktion schreiben kann, die möglichst portabel bleibt. Unter Windows gibt es eine, gibt es nach POSIX auch eine solche Funktion?
Aber '\0' wird nur dann erzeugt, wenn der Benutzer Ctrl-@ eingibt,
heißt das, dass in stdin buffer nicht 0-terminierende strings gespeichert werden?
-
@supertux: Wenn du den input-stream umleitest, willst du aller Wahrscheinlichkeit nach nicht den gesamten Puffer leeren; sonst kriegst du nämlich nachher überhaupt keinen input mehr. Die einzige Ausnahme, die mir gerade einfällt, sind pseudo terminals - und mit denen funzt das wieder auf die altmodische Art.
Ansonsten würde ich für solche und vergleichbare Dinge mal in die termios.h kucken, die ist für das terminal interface zuständig. Auf die Art kann man z.B. auch das terminal buffering ausschalten, was bewirkt, dass getchar() sich wie getch() aus dem DOS-I/O verhält - ich hab die starke Vermutung, dass es da auch für dieses Problem ne Lösung geben wird.
-
0xdeadbeef schrieb:
@supertux: Wenn du den input-stream umleitest, willst du aller Wahrscheinlichkeit nach nicht den gesamten Puffer leeren; sonst kriegst du nämlich nachher überhaupt keinen input mehr.
ok, beefy, das hast du Recht, hab grad auch getestet und konnte nichts mehr eingeben.
0xdeadbeef schrieb:
Ansonsten würde ich für solche und vergleichbare Dinge mal in die termios.h kucken, die ist für das terminal interface zuständig. Auf die Art kann man z.B. auch das terminal buffering ausschalten, was bewirkt, dass getchar() sich wie getch() aus dem DOS-I/O verhält - ich hab die starke Vermutung, dass es da auch für dieses Problem ne Lösung geben wird.
benutzt termios nicht ncurses, oder ist es umgekehrt?
-
ncurses benutzt termios.
-
Um fflush zu umgehen wurde auf einer Seite (http://www.bsdforen.de/archive/index.php/t-5514.html) der Befehl rewind vorgeschlagen:
Beschreibung
Setzt einen Dateizeiger auf den Stream-Anfang.rewind ist äquivalent zu fseek(stream, 0L, SEEK_SET), löscht aber nicht nur das Dateiende-Flag (wie rewind), sondern auch eventuell gesetzte Fehler-Flags.
In Dateien, die für Lese- und Schreibzugriffe geöffnet worden sind, kann nach rewind zwischen "Lesen" und "Schreiben" gewechselt werden.
So richtig passend klingt das ja nicht gerade, technisch würde diese Lösung jedoch funktionieren.
rewind(stdin);
Spricht etw. dagegen?
MfG
Simon S.
-
sehe ich genauso wie AJ: eine ansi-c-konforme möglichkeit, zu prüfen, ob der stdin-puffer leer ist, gibt es nicht.
das leeren des stdin-puffers geht bei den meisten ansi-c-bibliotheken mit fflush(stdin). das ist allerdings meines wissens auch nicht ansi-c-konform.
while(getchar()!='\n');
der gedanke, daß von der konsole nur ganze eingabezeilen mit abschließendem new-line kommen und man deshalb nur bist zum nächsten new-line lesen muß, um den eingabepuffer zu leeren, haut nicht hin. wenn der eingabestrom leer ist würde die schleife beim ersten aufruf von getchar() auf die nächste eingabe warten. und wenn er nicht leer ist, bestünde immer noch die möglichkeit, daß mehrere zeilen im eingabepuffer stehen. die schleife liest aber nur die erste aus.