Scanfs blockieren sich gegenseitig
-
Die Funktion
clear_streambuffer
macht nicht was der Name suggeriert.
Das ist eher eindiscard_to_endofline
Denn eine Fehleingabe durch die Entertaste wird damit nicht abgefangen,
da es nur bis zum nächsten '\n' liest. Alle Zeichen danach bleiben noch im Eingabestrom.
Also doch nicht gelöscht.
-
Also meine Erklärung von Streams war ja schon schlecht geschrieben, aber die von "kenner der c streams" ist schlichtweg falsch. Zeilenpuffer? Den Unsinn hatten wir doch neulich schon einmal und den gibt es schlichtweg nicht. Daher macht die Funktion auch nicht, was versprochen wird. Puffer, Zeilen, Tasten, all das gibt es in dem C-Programm nicht. Das ist manchmal Teil der Betriebsumgebung, dann und nur dann, wenn das Programm in einer Konsole mit Verbindung zu einer Tastatur läuft. Das C-Programm bekommt davon gar nichts mehr mit, auch wenn das Gesamtverhalten der Einheit Konsole+Tastatur+Programm sich scheinbar so verhält als wäre da ein Zeilenpuffer. Der ist aber nicht da und wenn man so programmiert als wäre er doch da, so wird es schon an kleiner Änderung der genannten Konfiguration nicht mehr funktionieren. Nicht einmal wenn man diese Einheit benutzt funktioniert es richtig, siehe DirkBs Einwand. Etwas weiteres, wo das trotz Konsole+Tastatur nicht funktioniert ist, wenn sehr schnell getippt wird, zum Beispiel mittels Copy&Paste.
-
DirkB schrieb:
Die Funktion
clear_streambuffer
macht nicht was der Name suggeriert.
Das ist eher eindiscard_to_endofline
Denn eine Fehleingabe durch die Entertaste wird damit nicht abgefangen,
da es nur bis zum nächsten '\n' liest. Alle Zeichen danach bleiben noch im Eingabestrom.
Also doch nicht gelöscht.bitte genau lesen.
das irgendwas gelöscht wird, habe ich nicht geschrieben.
ich habe auch nicht geschrieben, dass eine fehleingabe abgefangen wird.
ich habe geschrieben, dass die zeichen aus dem puffer eingelesen und verworfen werden, inklusive des newlines.
dein argument, dass danach alle zeichen im eingabestrom bleiben ist nicht unbegründet, denn wir wissen nicht wie der puffer aussieht. das ist aus der sicht des programms aber uninteressant, denn das programm "sieht" einen leeren puffer, beim nächsten scanf wartet das programm auf eine eingabe.SeppJ schrieb:
Also meine Erklärung von Streams war ja schon schlecht geschrieben, aber die von "kenner der c streams" ist schlichtweg falsch. Zeilenpuffer? Den Unsinn hatten wir doch neulich schon einmal und den gibt es schlichtweg nicht. Daher macht die Funktion auch nicht, was versprochen wird. Puffer, Zeilen, Tasten, all das gibt es in dem C-Programm nicht.
puffer gibt es nicht? herzlichen glückwunsch, sie haben den zonk gewonnen!
das ist falsch! natürlich gibt es puffer!das streams gepuffert ist, steht in vielen tutorials und büchern
High-level file access structures the file access through memory buffers.
These buffers hold data going to or coming from the file.http://www-control.eng.cam.ac.uk/~pcr20/C_Manual/chap13.html
hier eine übersicht verschiedener pufferstrategien:
http://www.gnu.org/software/libc/manual/html_node/Stream-Buffering.htmlman kann die pufferung sogar beeinflussen:
http://www.gnu.org/software/libc/manual/html_node/Controlling-Buffering.html#Controlling-Bufferingdas streams gepuffert sind, steht sogar im (c open)standard:
7.19.3 Files
At program startup, three text streams are predefined and need not be opened explicitly
— standard input (for reading conventional input), standard output (for writing
conventional output), and standard error (for writing diagnostic output). As initially
opened, the standard error stream is not fully buffered; the standard input and standard
output streams are fully buffered if and only if the stream can be determined not to refer
to an interactive device.
-
Dieser Puffer macht ganz was anderes als dieser ominöse "Zeilenpuffer", den du beschreibst. Selfowned.
ich habe geschrieben, dass die zeichen aus dem puffer eingelesen und verworfen werden, inklusive des newlines.
Und das passiert eben gerade nicht. Deine Funktion verwirft Zeichen aus dem Stream, bis '\n' oder EOF. Nix mit Puffer. Stehen aktuell keine Zeichen im Stream, so wird ggf. gewartet, bis welche kommen. Stehen zwei oder mehrere newlines direkt zur Verfügung (wie du sagen würdest "im Puffer"), wird das erste verworfen und dann ist Schluss. Denn da ist (von der Programmlogik her) kein Puffer. Nur ein Stream.
Dieser Puffer den du zitierst ist eine interne Optimierung der Streamfunktionen und hat mit der Programmlogik genau 0 zu tun. Alle Funktionen würden 100% gleichartig auf einem ungepufferten Stream funktionieren, es wäre bloß eventuell etwas lahmer.
-
SeppJ schrieb:
Deine Funktion verwirft Zeichen aus dem Stream, bis '\n' oder EOF. Nix mit Puffer. Stehen aktuell keine Zeichen im Stream, so wird ggf. gewartet, bis welche kommen. Stehen zwei oder mehrere newlines direkt zur Verfügung (wie du sagen würdest "im Puffer"), wird das erste verworfen und dann ist Schluss. Denn da ist (von der Programmlogik her) kein Puffer. Nur ein Stream.
nix mit puffer? lol! klar mit puffer. weil der stream gepuffert ist, also werden die sich im puffer befindenden zeichen eingelesen.
stehen zwei oder mehr newlines zur verfügung ... das ist ein argument lediglich theoretischer natur.
When a stream is fully buffered,
characters are intended to be transmitted to or from the host environment as a block when
a buffer is filled. When a stream is line buffered, characters are intended to be
transmitted to or from the host environment as a block when a new-line character is
encountered.siehst du, darum wirst du in einem gepufferten stream keine zwei oder mehr newlines auf einmal vorfinden.
und das hat jede menge mit logik zu tun. kenne ich das verhalten der streams, kann ich entsprechend logische programmabläufe bilden.
-
kenner der c streams schrieb:
siehst du, darum wirst du in einem gepufferten stream keine zwei oder mehr newlines auf einmal vorfinden.
Klar geht das.
Du gehst in deinem Beispiel doch von einer fehlerhaften Eingabe aus.
kenner der c streams schrieb:
... wenn z.b. 123abc eingegeben wurde...
Und wenn da zweimal (oder noch öfter) die Entertaste gedrückt wurde, stehen diese '\n' noch im Eingabestrom.
Deinclear_streambuffer
liest davon auch nur eins ein.
Wenn du Falscheingaben abfangen willst, musst du mehr machen.Und es ist völlig egal ob da ein Puffer ist, denn du hast
- keinen anderen Zugriff darauf als das Auslesen.
- keine Informatiun ob überhaupt ein Zeichen vorhanden ist.
- keine Information über das Alter der Eingabe.
- Du kannst ihn nicht löschen.Klar bieten Betriebssysteme solche Funktionen an.
Aber mit den Mitteln aus dem C-Standard geht das nicht.
-
Also bleibt alles in allem nur
while((c = getchar()) != '\n' && c != EOF){}
oder das verhasste
fflsuh(stdin)
übrig für den Anfänger?
-
kenner der c streams schrieb:
nix mit puffer? lol! klar mit puffer. weil der stream gepuffert ist, also werden die sich im puffer befindenden zeichen eingelesen.
Und wenn da nix ist? Oder mehr als du denkst? Hier kann ich schon aufhören, denn der Rest deines Arguments beruht ja auf der Fehlannahme, dass das irgendeinen Unterschied machen würde. Jedoch macht es keinen, wie du leicht an Testprogrammen feststellen kannst.
-
DirkB schrieb:
Du gehst in deinem Beispiel doch von einer fehlerhaften Eingabe aus.
kenner der c streams schrieb:
... wenn z.b. 123abc eingegeben wurde...
richtig!
DirkB schrieb:
Und wenn da zweimal (oder noch öfter) die Entertaste gedrückt wurde, stehen diese '\n' noch im Eingabestrom.
tun sie nicht.
nach dem ersten drücken der entertaste ist scanf fertig. das programm fährt fort und es wird die schleife ausgeführt, welche die falscheingabe verwirft.
es wird also nur der erste druck der enter-taste berücksichtigt.SeppJ schrieb:
Und wenn da nix ist?
hatte ich schon geschrieben.
wenn da nichts ist, wird auf eine eingabe gewartet.
hättst du selbst lesen können, aber bitte, für dich extra noch einmal:kenner der c streams schrieb:
diese funktion mit der schleife ist aber keine eierlegende wollmilchsau!
bedenke: beim aufruf dieser funktion wird auf eine eingabe gewartet, wenn sich
kein zeichen im puffer befinden!SeppJ schrieb:
Oder mehr als du denkst?
hatte ich auch schon geschrieben, als antwort auf deinen vorigen beitrag.
das such bitte selbst, ich zitiere mich nicht noch einmal selbst.
-
beginner88888 schrieb:
Also bleibt alles in allem nur
while((c = getchar()) != '\n' && c != EOF){}
oder das verhasste
fflsuh(stdin)
übrig für den Anfänger?
Kommt drauf an, wofür. Beide machen ganz was unterschiedliches. Das Erste (vom Standard gedeckt) macht, wie es DirkB so schön ausdrückt:
Die Funktion clear_streambuffer macht nicht was der Name suggeriert.
Das ist eher ein discard_to_endoflineWohingegen das Zweite (nicht vom Standard gedeckte Erweiterung von Microsoft) tatsächlich auf diesem internen Puffer arbeitet, von dem der Unregistrierte Nutzer hier meint, man könne da drauf zugreifen. Dies ist tatsächlich solch eine Möglichkeit, aber das ist ja auch kein standardkonformes C.
-
beginner88888 schrieb:
Also bleibt alles in allem nur
while((c = getchar()) != '\n' && c != EOF){}
genau das ist meine empfehlung.
beginner88888 schrieb:
oder das verhasste
fflsuh(stdin)
übrig für den Anfänger?
das hat laut standard undefiniertes verhalten, funktioniert aber bei diversen os(compilerbedingt) wie z.b. windows.
-
SeppJ schrieb:
von dem der Unregistrierte Nutzer hier meint, man könne da drauf zugreifen.
ja, das kann man.
die standardfunktionen getchar, scanf, etc. können das. sie greifen darauf zu und lesen daraus ein.
-
kenner der c streams schrieb:
DirkB schrieb:
Und wenn da zweimal (oder noch öfter) die Entertaste gedrückt wurde, stehen diese '\n' noch im Eingabestrom.
tun sie nicht.
nach dem ersten drücken der entertaste ist scanf fertig. das programm fährt fort und es wird die schleife ausgeführt, welche die falscheingabe verwirft.
es wird also nur der erste druck der enter-taste berücksichtigt.Sachlich falsch. Kannst du an Testprogrammen prüfen. Diskussion zu Ende?
diese funktion mit der schleife ist aber keine eierlegende wollmilchsau!
bedenke: beim aufruf dieser funktion wird auf eine eingabe gewartet, wenn sich
kein zeichen im puffer befinden!Soso. Also wohl doch keine Pufferleerung, sondern eine ganz normale Eingabefunktion?
hatte ich auch schon geschrieben, als antwort auf deinen vorigen beitrag.
Bloß war das "siehst du, darum wirst du in einem gepufferten stream keine zwei oder mehr newlines auf einmal vorfinden. " schlicht falsch. Also wohl doch nix mit Puffern.
Da ich mir ziemlich sicher bin, dass du der gleiche bist, der das Thema vor ein paar Wochen schon einmal diskutiert hat, spare ich mir mal die Gegenbeweisprogramme und weitere Argumente. Da du BEWEISE damals schon ignoriert hast, ist dir nicht zu helfen oder es ist absichtliche Trollerei. Falls du interessiert bist, ist das auch leicht selber zu testen.
@all: Falls den Typ irgendjemand ernst nimmt: Bitte melden. Dann konstruiere ich ein Gegenbeispiel.
-
SeppJ schrieb:
@all: Falls den Spinner irgendjemand ernst nimmt: Bitte melden. Dann konstruiere ich ein Gegenbeispiel.
ach, jetzt werden wir auch noch beleidigend?
immer schön sachlich bleiben, es sei denn du bist scharf darauf dir selbst armutszeugnisse auzustellen.
in dem fall darfst du gern so weiter machen"beweise" ?!
du meinst also dieses "gegenbeispiel":
http://ideone.com/oEMEPG
zeile 7 liest und verwirft das erste newline, zeile 8 liest und verwirft das zweite newline.
in zeile 10 und 11 wird in einer schleife genau das ausgegeben, was eingegeben wird. es wird zeichen für zeichen in den puffer geschrieben und sofort aus dem puffer gelesen und angezeigt. normales programmverhalten.
wo ist das jetzt ein gegenbeispiel?
-
Da braucht es kein anderes Programm, sondern nur eine andere Eingabe.
Und nach einem Druck auf die Enter-Taste, so wie die Aufforderung in dem Programm ist, ist das Programm nicht zu Ende.
Da muss man mindestens noch eine beliebige Taste und Enter drücken.
-
DirkB schrieb:
Da braucht es kein anderes Programm, sondern nur eine andere Eingabe.
Und nach einem Druck auf die Enter-Taste, so wie die Aufforderung in dem Programm ist, ist das Programm nicht zu Ende.
Da muss man mindestens noch eine beliebige Taste und Enter drücken.
selbstverständlich ist das programm nicht zu ende!
warum sollte das auch zu ende sein?!
das ist doch nicht mein beispiel!
hab ich doch auch schon längst geschrieben, das die besagte schleife auf eine eingabe wartet, wenn nix im eingabestrom ist!