Ich habe angefangen zu lesen " Die Programmiersprache C " (K & amp; R) und ich habe Zweifel über die Funktion getchar()
.
Zum Beispiel dieser Code:
%Vor% Eingabe toomanychars
+ STRG + D (EOF) druckt nur t
. Ich denke, das wird erwartet, da es der erste Charakter ist, der eingeführt wird.
Aber dann dieses andere Stück Code:
%Vor% Eingabe toomanychars
+ STRG + D (EOF) druckt toomanychars
.
Meine Frage ist, warum passiert das, wenn ich nur eine einzige char-Variable habe? Wo sind die restlichen Zeichen gespeichert?
BEARBEITEN:
Danke an alle für die Antworten, ich fange jetzt an, es zu bekommen ... nur einen Haken:
Das erste Programm wird beendet, wenn STRG + D angegeben wird, während das zweite Programm die ganze Zeichenfolge ausgibt und dann auf weitere Benutzereingaben wartet. Warum wartet es auf eine andere Zeichenfolge und wird nicht wie die erste beendet?
Es behandelt den Eingabestream wie eine Datei. Es ist so, als ob Sie eine Datei geöffnet hätten, die den Text "toomanychars" enthält, und sie einzeln lesen oder ausgeben.
Im ersten Beispiel, in Abwesenheit einer while-Schleife, ist es so, als hätten Sie eine Datei geöffnet und das erste Zeichen gelesen und dann ausgegeben. Das zweite Beispiel liest jedoch weiterhin Zeichen, bis es ein Dateiende-Signal ( ctrl+D
in Ihrem Fall) erhält, genau so, als würde es von einer Datei auf der Festplatte lesen.
In Antwort auf Ihre aktualisierte Frage, welches Betriebssystem verwenden Sie? Ich habe es auf meinem Windows XP Laptop ausgeführt und es hat gut funktioniert. Wenn ich Enter drücke, würde es ausdrucken, was ich bisher hatte, eine neue Zeile erstellen und dann fortfahren. (Die Funktion getchar()
kehrt erst zurück, wenn Sie die Eingabetaste drücken, dh, wenn beim Aufruf des Eingabepuffers nichts vorhanden ist). Wenn ich CTRL+Z
(EOF in Windows) drücke, wird das Programm beendet. Beachten Sie, dass das EOF in Windows in einer eigenen Zeile sein muss, um in der Eingabeaufforderung als EOF zu zählen. Ich weiß nicht, ob dieses Verhalten in Linux nachgeahmt wird, oder welches System auch immer Sie gerade ausführen.
getchar
erhält ein einzelnes Zeichen von der Standardeingabe, in diesem Fall ist dies der Tastaturpuffer.
Im zweiten Beispiel befindet sich die getchar
-Funktion in einer while
-Schleife, die fortfährt, bis sie auf EOF
trifft, so dass sie weiterläuft und ein Zeichen abruft (und das Zeichen auf dem Bildschirm ausgibt) bis zur Eingabe wird leer.
Aufeinander folgende Aufrufe von getchar
erhalten aufeinanderfolgende Zeichen, die von der Eingabe kommen.
Oh, und fühlen Sie sich nicht schlecht, diese Frage zu stellen - ich war verwirrt, als ich das erste Mal auf dieses Problem stieß.
Etwas ist hier gepuffert. z.B. Die stdout FILE *, in die putchar schreibt, könnte line.buffered sein. Wenn das Programm endet (oder auf eine neue Zeile stößt), wird eine solche FILE * -Filterung durchgeführt und Sie sehen die Ausgabe.
In einigen Fällen puffert das tatsächliche Terminal, das Sie gerade betrachten, die Ausgabe bis zu einem Newline oder bis das Terminal selbst angewiesen wird, den Puffer zu leeren, was der Fall sein könnte, wenn das aktuelle Vordergrundprogramm seither nicht mehr existiert neue Aufforderung.
Nun, was hier wahrscheinlich der Fall ist, ist, dass es die Eingabe ist, die gepuffert ist (zusätzlich zur Ausgabe :-)) Wenn Sie die Tasten drücken, wird es auf Ihrem Terminalfenster erscheinen. Das Terminal wird diese Zeichen jedoch nicht an Ihre Anwendung senden, es wird gepuffert, bis Sie es mit Ctrl + D als End-of-input angeben, und möglicherweise auch als Newline. Hier ist eine andere Version, um herumzuspielen und darüber nachzudenken:
%Vor%Versuchen Sie, Ihrem Programm einen Satz zu geben, und drücken Sie die Eingabetaste. Und mach dasselbe, wenn du auskommst if (c! = '\ n') Vielleicht können Sie feststellen, ob Ihre Eingabe, Ausgabe oder beide auf irgendeine Weise gepuffert sind. Dies wird interessanter, wenn Sie das obige wie folgt ausführen: ./mytest | ./mytest
(Beachten Sie, dass CTRD + D weder ein Zeichen noch EOF ist. Aber auf manchen Systemen wird der Eingabestrom geschlossen, was wiederum EOF an jeden richtet, der versucht, aus dem Stream zu lesen.)
Sie verwenden nur die Variable c
, um jedes Zeichen einzeln zu enthalten.
Sobald Sie das erste Zeichen ( t
) mit putchar(c)
angezeigt haben, vergessen Sie den Wert von c
, indem Sie der Variablen o
das nächste Zeichen ( c
) zuweisen und das vorherige Zeichen ersetzen Wert ( t
).
Für Ihre aktualisierte Frage wird im ersten Beispiel nur ein Zeichen gelesen. Es erreicht nie den EOF. Das Programm wird beendet, da nach Abschluss der printf-Anweisung nichts zu tun ist. Es liest nur ein Zeichen. Druckt es. Fügt eine neue Zeile ein. Und dann endet es, da es nichts mehr zu tun hat. Es liest nicht mehr als ein Zeichen.
Während im zweiten Code getchar und putchar in einer while-Schleife vorhanden sind. Dabei liest das Programm Zeichen nacheinander (wie es von der Schleife gemacht wird), bis die Reichweite das EOF-Zeichen erreicht (^ D). An diesem Punkt entspricht es c! = EOF und da die Bedingungen nicht erfüllt sind, kommt es aus der Schleife heraus. Jetzt müssen keine weiteren Anweisungen ausgeführt werden. Also endet das Programm an diesem Punkt.
Hoffe, das hilft.
Tags und Links c loops io kernighan-and-ritchie