mit getchar() mehrere zeichen einlesen?
-
#include <stdio.h>
int main()
{
int c;c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}}
hallo... ich habe mir vor einigen tagen das K&R buch gekauft uns stehe nun vor einem rätsel. wie funktioniert diese schleife? ich verstehe nicht wieso man mit getchar mehr als ein zeichen einlesen kann und nach drücken der enter-taste alle wieder ausgegeben werden. ich dachte mir mit getchar kann immer nur ein zeichen eingelesen werden und in der int variable c gespeichert werden.?
lg franz
-
getchar() liest ein Zeichen ein, putchar() gibt ein Zeichen aus. Soweit hast Du das schon richtig verstanden. Aber: stdin ist zeilengepuffert. Was heisst das? Stell Dir vor, irgendwo zwischen der Tastatur und Deinem Programm sitzt der Eingabepuffer. Der sammelt erstmal Zeichen, bis eine Zeile voll ist (= bis auf der Tastatut Enter gedrückt wird). Und erst dann, wird die Zeile als ganzes an die nächste Stufe weitergegeben. Und von da liest getchar dann. Und deshalb wartet getchar() erstmal 'ne ganze Zeit, liest dann aber in der Schleife jeweils ein Zeichen zur Zeit, aber halt alle direkt nacheinander.
-
vielen dank für die schnelle antwort:)
also ließt getchar() (zeile 7) bei der eingabe von "Hallo" erst mal das 'H' ein und putchar() (in der schleife) gibt es dann aus. danach wird das 'a' eingelesen usw. bis die ENTERTASTE erreicht ist. und dann wartet getchar() wieder auf die eingabe. kann ich mir das als einen stapel zettel vorstellen wobei getchar() immer den obersten nimmt bis der boden (ENTER) erreicht ist und dann erst wieder nach einem neuen stapel fragt?.
lg franz
-
Ja, das Bild passt, würde ich sagen.
-
franzulat schrieb:
vielen dank für die schnelle antwort:)
also ließt getchar() (zeile 7) bei der eingabe von "Hallo" erst mal das 'H' ein und putchar() (in der schleife) gibt es dann aus. danach wird das 'a' eingelesen usw. bis die ENTERTASTE erreicht ist. und dann wartet getchar() wieder auf die eingabe. kann ich mir das als einen stapel zettel vorstellen wobei getchar() immer den obersten nimmt bis der boden (ENTER) erreicht ist und dann erst wieder nach einem neuen stapel fragt?.
lg franz
Nein. Aber du bist schon nahe dran. getchar nimmt einfach nur den nächsten Zettel von einem Stapel, der heißt stdin. Wenn keiner da ist, dann wird gewartet, bis ein weiterer Zettel kommt. Aber getchar fragt nie nach neuen Zetteln und es füllt auch nie den Zettelstapel nach. Das macht irgendetwas außerhalb deines Programms. Gewöhnlicherweise die Konsole, kann aber auch etwas anderes sein. Und die (zumindest die Konsolen) geben ihre Zettel normalerweise erst an den stdin-Stapel deines Programms weiter, wenn sie einen Zettel mit der Aufschrift "ENTER" erhalten haben.
-
franzulat schrieb:
hallo... ich habe mir vor einigen tagen das K&R buch gekauft
Gratulation. Das hast du schon mal besser gemacht als die meisten Neulinge hier.
franzulat schrieb:
wie funktioniert diese schleife?
Der C-Standard definiert einen Eingabestrom (stream), auch bekannt als stdin.
Dieser arbeitet standardgemäß gepuffert, d.h. er nimmt erstmal alle auf diesem Strom eintreffenden Daten (üblicherweise eingetippte Zeichen der Tastatur) entgegen und speichert sie zwischen (puffert sie). Das ist nun mal so, nehme es als gegeben hin.
Beim Start eines C-Programms (main) ist dieser stdin-Puffer erstmal leer, das Programm läuft bei main los.
Der Programmablauf stoppt bei der ersten Leseaktion auf stdin, in deinem Fall also getchar. (kannst du mit dem Debugger testen).
Der Programmlauf geht erst weiter, wenn im Standardeingabestrom (stdin) ein '\n'/<ENTER> ankommt (in Ausnahmefällen, die hier nicht zur Debatte stehen, reicht auch EOF/D,Z).
Wenn '\n' eingetroffen ist, hört die Blockierung des Programmlaufs auf, der Code nach getchar wird ausgeführt, nach dem FIFO Prinzip liefert der erste getchar Aufruf das ersteingegebene Zeichen zurück, und alle folgenden getchar-Aufrufe räumen jeweils ein Zeichen aus dem internen stdin-Puffer ab.
Ist der Puffer leergeräumt (kein Zeichen mehr vorhanden) und eine weitere Leseaktion auf stdin (z.B. getchar) tritt im Programmlauf auf, stoppt der Programmlauf wieder und der o.g. Eiertanz geht von vorn los.
Über Sinn und Zweck dieses Verfahrens kann man geteilter Meinung sein, über die Standardkonformität nicht.
Über Eingabeumlenkung beim Programmaufruf aus der Kommandozeile/Shell kann man einen 'automatisierten' Ablauf erreichen, der Anwender muss nicht interagieren, eine Batch/Skript-Datei kann die stdin-Inputs liefern, also z.B../a.out < dateimitinput.txt
oder
echo blafasel | a.exe
Es gibt verschiedene (nicht standardkonforme und damit nichtportable) Möglichkeiten, diese Blockierung bei '\n' zu umgehen, getch(),_getch(),kbhit() usw.
-
nochmals vielen dank für eure antworten. hier wird einem wirklich schnell geholfen:) lg Franz