2010-09-09 16 views
38

Ich bin durch ein Programm verwirrt, das in K & R erwähnt wird, das getchar() verwendet. Es gibt die gleiche Ausgabe wie die Eingabezeichenfolge:Wie funktioniert getchar()?

#include <stdio.h> 

main(){ 
    int c; 
    c = getchar(); 
    while(c != EOF){ 
     putchar(c); 
     c = getchar(); 
    } 
} 

Warum wird die gesamte Zeichenfolge gedruckt? Ich würde erwarten, dass es einen Charakter liest und erneut nach dem Input fragt.

Und, sind alle Zeichenfolgen, die wir eingeben, durch ein EOF beendet?

+0

Isnt EOF ein Zeichenwert und kein int? –

+3

Ich denke, es ist ein int, dessen Wert -1 ist. – Shubham

+2

Zeichenfolgen werden von \ 0 beendet. Dateien werden durch EOF beendet, das ist -1 –

Antwort

34

In dem einfachen Setup werden Sie wahrscheinlich verwenden, getchar Arbeiten mit Eingang gepuffert, so geben Sie drücken müssen, bevor getchar alles zu lesen bekommt. Zeichenfolgen werden nicht durch EOF beendet; Tatsächlich ist EOF nicht wirklich ein Zeichen, sondern ein magischer Wert, der das Ende der Datei anzeigt. Aber EOF ist nicht Teil der Zeichenfolge gelesen. Es ist, was getchar zurückgibt, wenn nichts mehr zu lesen ist.

+0

Als ich das count-char-Programm in K & R ausprobierte, fand ich, dass 'char()' meine Eingabe wie "abc" bekommt Zählen, es wäre "4" statt "3", also habe ich 'gdb' verwendet, um es zu debuggen, es stellte sich heraus, dass das zusätzliche 'Zeichen' (nl) ist, dessen ASCII-Code 0x0a ist. Also, war meine Eingabe eine Zeichenfolge? Wurde diese Zeichenfolge nicht mit '\ 0' beendet? Warum gab es ein (nl)? – ray6080

+0

Das liegt daran, dass das Zeilenvorschubzeichen, das die Zeile beendet, Teil der Eingabe ist. C ist so, geh damit um. –

3

getchar() liest ein einzelnes Zeichen der Eingabe und gibt dieses Zeichen als Wert der Funktion zurück. Wenn beim Lesen des Zeichens ein Fehler auftritt oder das Ende der Eingabe erreicht wird, gibt getchar() einen speziellen Wert zurück, der durch "EOF" dargestellt wird.

26

Es gibt einen zugrunde liegenden Puffer/Stream, aus dem getchar() und Freunde gelesen werden. Wenn Sie Text eingeben, wird der Text irgendwo in einem Puffer gespeichert. getchar() kann ein Zeichen gleichzeitig durchlaufen. Jeder Lesevorgang gibt das nächste Zeichen zurück, bis das Ende des Puffers erreicht ist. Der Grund, warum Sie nicht nach folgenden Zeichen fragen, ist, dass es den nächsten aus dem Puffer holen kann.

Wenn Sie Ihr Skript ausführen und direkt darin eingeben, werden Sie weiterhin zur Eingabe aufgefordert, bis Sie STRG + D (Ende der Datei) drücken. Wenn Sie es wie ./program < myInput aufrufen, wo MyInput eine Textdatei mit einigen Daten ist, wird es das EOF erhalten, wenn es das Ende der Eingabe erreicht. EOF ist kein Zeichen, das im Stream vorhanden ist, sondern ein Sentinel-Wert, der angibt, wann das Ende der Eingabe erreicht wurde.

Als eine zusätzliche Warnung, ich glaube, getchar() wird auch EOF zurückgeben, wenn es einen Fehler auftritt, so dass Sie ferror() überprüfen möchten. Beispiel unten (nicht getestet, aber Sie bekommen die Idee).

main() { 
    int c; 
    do { 
     c = getchar(); 
     if (c == EOF && ferror()) { 
      perror("getchar"); 
     } 
     else { 
      putchar(c); 
     } 
    } 
    while(c != EOF); 
} 
+1

Vielen Dank für die STRG + D Info. – estrar

+0

Erzeugt "Bash" den Puffer oder Linux? Es erscheint merkwürdig, dass K & R dieses Problem nicht erwähnt hat, besonders da sie Unix-basiert waren. Vielen Dank. – Ron

9

Streicher, von C Definition werden durch '\0' beendet. Sie haben keine "C strings" in Ihrem Programm.

Ihr Programm liest Zeichen (gepuffert bis ENTER) von der Standardeingabe (der Tastatur) und schreibt sie zurück auf die Standardausgabe (den Bildschirm). Dies geschieht unabhängig davon, wie viele Zeichen Sie eingeben oder wie lange Sie dies tun.

Um das Programm zu stoppen, müssen Sie angeben, dass die Standardeingabe keine Daten mehr enthält (wie kann eine Tastatur keine Daten mehr haben?).

Sie geben einfach Ctrl+D (Unix) oder Ctrl+Z (Windows) ein, um so vorzugehen, dass die Datei ihr Ende erreicht hat.
Ctrl+D (oder Ctrl+Z) sind nicht wirklich Zeichen im C Sinn des Wortes.

Wenn Sie Ihr Programm mit Eingabeumleitung ausführen, ist die EOF das tatsächliche Ende der Datei, keinen Make Glauben eines
./a.out < source.c

2

Nach der Definition von getchar() liest ein Zeichen von der Standardeingabe. Leider wird stdin für keyboard gehalten, was für getchar nicht der Fall ist. getchar verwendet einen Puffer als stdin und liest jeweils ein Zeichen. In Ihrem Fall, da es kein EOF gibt, laufen getchar und putchar mehrmals und es sieht für Sie so aus, als ob die ganze Zeichenfolge gleichzeitig ausgedruckt wird. machen Sie eine kleine Änderung und Sie werden verstehen:

Schauen Sie sich jetzt die Ausgabe im Vergleich zum ursprünglichen Code.

Ein weiteres Beispiel, das Sie das Konzept der getchar und gepuffert stdin wird erklären:

void main(){ 
int c; 
printf("Enter character"); 
c = getchar(); 
putchar(); 
c = getchar(); 
putchar(); 
} 

Geben Sie zwei Zeichen im ersten Fall. Das zweite Mal, wenn getchar läuft, gibst du einen Charakter ein? Nein, aber putchar funktioniert trotzdem.

Dies bedeutet letztlich, dass es einen Puffer gibt und wenn Sie immer etwas eingeben und klicken Sie auf Enter, das geht und legt sich im Puffer. getchar verwendet diesen Puffer als stdin.

Verwandte Themen