Frage zum löschen des Inputpuffers
-
hi.
ledi schrieb:
Offenbar wird hier der Tastaturpuffer gelöscht?
ja, die zeile soll den eingabepuffer löschen.
(ich sehe keine probleme darin, den seit jahrzehnten üblicherweise gewählten begriff puffer auch weiterhin zu benutzen. die zeichen werden während der eingabe gepuffert).in der schleife werden die zeichen mit getchar solange einzeln aus dem puffer eingelesen, bis ein EOF oder ein '\n' zurückgegeben wird und die schleife abbricht. danach hat man für weitere eingaben einen leeren, sauberen puffer.
man könnte sich jetzt fragen, wie das '\n' in den puffer überhaupt hinein kommnt.
tja, das ist die eigenschaft von schanf, getchar und zum teil auch von fgets. scanf/getchar schreiben beim abschluss einer eingabe, also wenn man die enter-taste drückt, das '\n' an das ende des puffers.
zu programmstart ist der puffer nämlich leer. das kann man überprüfen, indem manint c; while ((c = getchar()) != EOF && c != '\n') ;
an den anfang des programms schreibt, das programm startet und feststellt,
das man aus der schleife nur dann herauskommt, wenn man die enter-taste drückt.ledi schrieb:
Warum nicht mit fflusch(stdin); ?
Kann man machen, funktioniert aber nicht auf jedem system und ist daher
nicht standardgemäß. fflusch(stdin) kann auf manchen systemen zu undefiniertem verhalten führen. darum geht man gern standardkonforme wege.ledi schrieb:
Kann mir bitte jemand erklären was die Programmzeile hier für einen Sinn macht?
in deinem programmbeispiel macht die zeile m.m.n. offengestanden genau 0 sinn.
-
ok,
d.h. ich muss einen inputstream genau so (und nur so) beenden?
Gibt es auch andere Varianten?
Oder wie würdest du das hier in diesem konkreten Beispiel lösen?
-
ledi schrieb:
ok,
d.h. ich muss einen inputstream genau so (und nur so) beenden?
Nein. Was meinst du überhaupt mit Beenden?
Gibt es auch andere Varianten?
Es gibt immer viele Wege. Wenn es um das "Problem" der Mischung formatierter und unformatierter Eingabefunktionen geht, dann sollte man sich zum Beispiel mal die Feinheiten des scanf-Formatstrings angucken, was dort so alles möglich ist.
Oder wie würdest du das hier in diesem konkreten Beispiel lösen?
Ich würde Zeilen 20 und 21 komplett weglassen. Wenn man ein Konsolenprogramm ausführen will, dann nehme man eine Konsole. Und wenn man eine Konsole genommen hat, dann nervt so etwas wie Zeile 20 und 21 nur, weil es genau das umgekehrte Verhalten erzeugt, das man normalerweise von einem Konsolenprogramm erwartet.
-
Der Puffer wird nicht gelöscht.
Es werden nur die Zeichen bis zum nächsten '\n' (oder EOF) gelesen.Alle weiteren Zeichen bleiben im Puffer.
Die meisten IDEs bieten die Möglichlkeit die Konsolenfenster offen zu lassen, bzw. nochmal anzeigen zu lassen.
Daher ist dein getchar gar nicht nötig.
-
das programm startet doch mit einem leeren puffer, warum sollte es in diesem fall weitere zeichen vor dem scanf aufruf geben?
-
b.b. schrieb:
das programm startet doch mit einem leeren puffer, warum sollte es in diesem fall weitere zeichen vor dem scanf aufruf geben?
Nochmal: Es gibt keinen Puffer!
Das ist ein komplett falsches Bild davon, was da abläuft und alle komplexeren Folgerungen daraus sind falsch. Du hast eine Kette von Zeichen, die geht in dein Programm rein und da kannst du nix dran ändern, du kannst nur unterschiedlich darauf reagieren. Dein Programm steuert nicht die Tastatur und auch nicht den Monitor, das machen andere Programme mehrere Abstraktionsschichten über der C-Runtime, die sind dann so nett die Zeichen von der Tastatur an dein Programm weiterzuleiten oder die Ausgabe deines Programms auf dem Monitor zu zeigen. Auf der Ebene deines Programms ist ein eventueller Tastaturpuffer längst Geschichte, weil der ganz woanders sitzt. Wenn eine der Abstraktionsebenen zwischen deinem Programm und der Tastatur entscheidet, dass dein Programm nicht mehr Zeichen von der Tastatur sondern aus einer Datei erhalten soll, dann bekommt dein Programm die Zeichen daher und dein Programm kann den Unterschied nicht feststellen! Das ist auch kein exotischer Vorgang, das Umleiten der Standard-Ein- und Ausgabe ist das kleine Einmaleins für jeden der ein unixoides System ernsthaft benutzt. Die Quelle der Zeichen ist auch nicht unbedingt gepuffert, die ganze Frage macht daher einfach keinen Sinn.
-
die über die tastatur eingegebenen zeichen müssen irgendwo zwischengespeichert werden, bevor sie mit getchar oder scanf abgeholt werden.
dieser zwischenspeicher wird üblicherweise puffer genannt, vermutlich entnommen aus dem englischen wort buffer.
(ein strom wird es erst dann, wenn ich die enter-taste drücke, dann wird - wuuuuusch - der inhalt aus dem puffer nach stdin "geströmt".)das ist doch bloß eine frage der interpretation.
die ganze c-welt benutzt das wort puffer/buffer, ich weiß gar nicht warum du da jetzt so einen hermann von machst.wenn die quelle gar nicht gepuffert wäre (was nicht heißen soll, dass sie gepuffert sein muss), dann hätten wir das problem des puffer-leerens gar nicht erst und es wäre kein "restmüll" im puffer nach einem scanf-aufruf. :p
-
Deine Vorstellung ist komplett falsch. scanf funktioniert so nicht. stdin funktioniert so nicht. Noch einmal erklär ich es dir aber nicht. Fall eben auf die Schnauze mit deinen falschen Vorstellungen, wenn du nicht lernen möchtest.
-
komplett falsch, soso, interessant. du willst mir also erzählen, dass die tastatureingabe nicht zwischengespeichert wird.
also, ich habe z.b.
int number; scanf("%d", &number);
der benutzer gibt z.b. ein: 123 und dann drückt er die eingabetaste.
für mich ist es jetzt klar, dass die zeichen '1', '2', '3' irgendwo
zwischengespeichert(gepuffert) werden müssen, bevor sie von scanf interpretiert und nach erfolgreicher auswertung und umwandlung als eine
dezimalzahl in der übergebenen variable number gespeichert werden -
für dich ist dieser puffer(zwischenspeicher) ein magic-stream.
das ist völlig im ordnung, jeder hat so seine eigene vorstellung. :pbtw. lerne ich sehr gern dazu, ich weiß gar nicht wie du auf das schmale brett kommst, dass dem nicht so wäre.
-
Wenn da ein Puffer ist, dann zeig mal, wie man ihn löscht.
-
SeppJ schrieb:
Wenn da ein Puffer ist, dann zeig mal, wie man ihn löscht.
gern.
int c; while ((c = getchar()) != EOF && c != '\n') ;
wenn zeichen noch im puffer waren, sind sie nach dem
abarbeiten der schleife nicht mehr per getch, scanf, fgets, etc. zugänglich.
ob die zeichen wirklich noch im puffer stehen, oder intern lediglich ein zeiger verbogen wurde, ist prinzipell wurst.
für den anwendungsprogrammierer hat das den effekt einer pufferleerung
(oder von mir aus auch eines leeren zeichenstroms).
-
Der "Puffer" wird nicht geleert.
Eingabe1 einige Zeit warten (oder lange Berechnung) Puffer leeren Eingabe2
Wenn der Puffer geleert wird, sollte nichts von den Eingaben während der Wartezeit bei der Eingabe2 auftauchen.
Bei dem
while ((c = getchar()) != EOF && c != '\n');
wird aber nur bis zum ersten '\n' aus dem Stream gelesen. Der Rest bleibt drin.
-
Und du glaubst wirklich, dass ich nicht genau diese falsche Antwort erwartet habe?
Dieses Programm löscht eine Zeile, ganz egal wann oder wie diese eingegeben wurde. Ist keine ganze Zeile da, dann wartet es, bis irgendwoher ein Zeilenumbruch kommt. Nix vonwegen Puffer löschen, die Zeile muss sogar eventuell noch eingegeben werden und wird dann ignoriert!
-
Der Rest bleibt drin.
kann man denn ein beispiel programmieren/konstruieren, bei dem das so ist?
das also nach der ausführung der while schleifewhile ((c = getchar()) != EOF && c != '\n');
noch weitere zeichen mit getchar, scanf, fgets etc. eingelesen und angezeigt werden können?
-
b.b. schrieb:
kann man denn ein beispiel programmieren/konstruieren, bei dem das so ist?
-
SeppJ schrieb:
b.b. schrieb:
kann man denn ein beispiel programmieren/konstruieren, bei dem das so ist?
haha, sehr witzig!
-
b.b. schrieb:
kann man denn ein beispiel programmieren/konstruieren, bei dem das so ist?
das also nach der ausführung der while schleifewhile ((c = getchar()) != EOF && c != '\n');
noch weitere zeichen mit getchar, scanf, fgets etc. eingelesen und angezeigt werden können?
Setzt meinen Pseudocode in C um.
Direkt nach der ersten Eingabe drückst du die Entertaste mehrmals.
-
DirkB schrieb:
Direkt nach der ersten Eingabe drückst du die Entertaste mehrmals.
dadurch schreibt scanf wieder ein \n in den puffer rein, ist doch klar das der puffer dann nicht mehr leer ist.
-
scanf ist das '\n' beim einlesen von Zahlen egal.
Da werden Whitespace überlesen.
Das Problem tritt dann auf, wenn danach das '\n' zur Eingabe passt, wie bei fgets oder getchar.scanf schreibt auch nur das erste Zeichen, das nicht mehr zum Formatspecifier passt, in den Eingabestrom zurück.
Das können alle möglichen Zeichen sein. Bei %d z.B. die Buchstaben und die Sonderzeichen (bis auf + oder - am Anfang).
Bei %o sogar die 8 und 9.Nimm das Beispiel vom TO und schreib in Zeile 17 einen Wartebefehl (sleep(30) oder ähnliches).
In der Zeit (30 Sekunden) kannst du dann Eingaben machen (mit Entertaste). Da kommt kein scanf vor, das irgendwas "in den Puffer schreibt".
-
okay, ich habe einen weg gefunden, nämlich die eingabe über den NUM-block
( mehrmaliges alt+10 nacheinander ),
dass nach einem entertasten-druck und
anschließendemwhile ((c = getchar()) != EOF && c != '\n');
noch weitere \n im puffer bleiben
. nachprüfbar mit:
int c; getchar(); while ((c = getchar()) != EOF && c != '\n'); while(1) printf("%d,", getchar()); }
eingabe z.b.:
alt+10 alt+10 alt+10 ENTER
ausgabe:
10,10,verdammt