2008-12-05 6 views
7

Jede Idee, warum der folgende Code nicht die Menge der Zeichen in der Eingabe druckt? Ich habe das gerade aus dem K & R Buch genommen. C im Moment zu lernen und das ist wirklich verwirrend, sieht für mich so aus, als würde ich nie EOF erreichen. Wenn das der Fall ist, warum sollte das dann als Beispiel dienen?C-Programmierung Übung aus der K & R Buch

#include <stdio.h> 

main() 
{ 
    double nc; 

    for (nc = 0; getchar() != EOF; ++nc) 
     ; 
    printf("%d\n", nc); 
} 

Antwort

12

Das Programm sieht korrekt aus, Ihr Problem ist, dass Sie nach der Eingabe EOF (Dateiende) an die Befehlszeile senden müssen, da die Standardeingabe als Datei behandelt wird. Ich denke, in einem Linux-Terminal können Sie Strg + D drücken, um EOF zu senden ... Ich bin mir nicht sicher, wie man es in anderen Betriebssystemen macht. Um dieses Programm zu testen, möchten Sie vielleicht EOF zu '\n' ändern, was dazu führt, dass es stoppt, wenn Sie Enter drücken.

+1

CTRL Z im DOS-Land – EvilTeach

+0

Warum habe ich zwei Downvotes bekommen? –

+1

FWIW, ich habe dich nicht abgelehnt. Es gibt jedoch kein EOF-Zeichen, das könnte der Grund sein. Wenn ein Benutzer^D (oder was auch immer) auf einem Terminal drückt, verursacht es eine EOF-Bedingung auf dem Prozess 'stdin' (es wird von der Shell geschlossen), es ist kein Charakter beteiligt. – Chris

1

Dieser Code liest Zeichen aus der Standardeingabe. Wenn Sie dieses Programm normal ausführen, stammt die Standardeingabe vom Benutzer. In diesem Fall gibt es keine Möglichkeit, EOF an das Programm zu senden.

Dieser Code wird funktionieren, wenn Sie eine Datei mit dem Standard in (./myprogram < tempfile.txt) umleiten.

+0

Warum wird es als ein Beispiel in seiner aktuellen Form verwendet, wenn es keine Möglichkeit gibt (in seiner aktuell beabsichtigten Form), zur printf-Funktion zu gelangen? –

+0

Sind Sie sicher, dass sie nicht möchten, dass Sie die Weiterleitung verwenden? Auch wenn Sie es genau so eingegeben haben, wie das Beispiel aussieht, dann sieht es so aus, als ob dieses Buch ziemlich alt ist, vielleicht funktioniert es, oder es arbeitet auf einer bestimmten Plattform (die vielleicht nicht mehr da ist, wie DOS). – SoapBox

+0

Insbesondere die Definition von main(), wo es keinen Rückgabetyp gibt, und die Verwendung von double für die for-Schleife lassen mich das Alter und die Nützlichkeit dieses Buches hinterfragen. – SoapBox

7

Das Programm hält Lese von Daten von stdin bis EOF empfangen wird, wird dies durch Drücken von Strg-D am Anfang einer Zeile auf einer Unix-Konsole oder Strg-Z am Anfang einer Zeile in einer Windows-Konsole durchgeführt. Nachdem Sie auf diese Weise EOF signalisiert haben, wird die printf Funktion ausgeführt, die die Anzahl der gelesenen Zeichen anzeigt.

6

Ihre nc ist eine doppelt verwendbare printf("%lf", nc) zu drucken verdoppelt. Statt

versuchen diese

#include <stdio.h> 

int main(void) 
{ 
    int nc; 

    for (nc = 0; getchar() != EOF; ++nc) 
     ; 
    printf("%d\n", nc); 

    return 0; 
} 
+0

Ooh, gute Abholung. –

+0

Obwohl etwas falsch, ist% f für doubles. Es kann auch für Floats verwendet werden, da es auf Variablenargumentfunktionen hochgesetzt wird. – Chris

+0

Danke, aber ich werde mit% lf bleiben, wie das gute Buch sagt # include int main (void) { lange float x = 3,14159265358979; float y = 3,14159265358979f; printf ("% 15.10f \ n", y);/* 3.1415927410 */ printf ("% 15.10lf \ n", x);/* 3.1415926536 */ Rückgabe 0; } – EvilTeach

5

Ich möchte die Antworten bisher gegeben klären, weil sie scheinen, Phrasen wie „EOF senden“, „erhielt EOF“, „EOF-Zeichen“ usw. Laut den Kommentaren (Danke) zu dieser Antwort, "sende EOF" und "empfangen EOF" sind legitime Begriffe, aber bitte denke nicht, dass es ein Charakter ist.

EOF ist kein überhaupt Charakter. Es ist der Wert, den getchar() (oder fgetc/getc) zurückgibt, wenn der Datenstrom am Ende der Datei liegt oder ein Lesefehler auftritt. Es ist lediglich ein spezieller Wert außerhalb des Bereichs der Zeichenwerte, den getchar() zurückgibt, der die -Bedingung des Fehlers oder Dateiendes anzeigt.

Es wird von dem C-Standard als negativ, während GetChar kehrt Zeichen als unsigned char in int umgewandelt definiert.

Edit: Auf einigen Recherchen, die ich vor dem Absatz getan haben sollte ich das hier verwendet geschrieben zu sein, ich habe einige meiner Annahmen realisiert völlig falsch waren. Danke an den Kommentator, der darauf hingewiesen hat.

Sobald ein Datenstrom (z. B. stdin) in der End-of-File-Bedingung ist, kann diese Bedingung mit clearerr() zurückgesetzt werden und getchar() kann mehr Daten von stdin lesen.

+0

Wow, hier gibt es einiges zu korrigieren: 1) niemand hat EOF ein Zeichen genannt, 2) "Senden/Empfangen EOF" sind völlig legitime Phrasen, 3) das kontrollierende Terminal schließt Ihre Dateien nicht, 4) stdin ist nicht geschlossen Wenn EOF von getchar zurückgegeben wird, kannst du nach dem Empfangen von EOF weiterhin von stdin lesen ... –

+0

1) Eigentlich hat Jeremy Ruten das getan und ich korrigierte ihn und er redigierte seine Antwort; Siehe den Überarbeitungsverlauf. 2) Okay 3) Ich hätte die Shell sagen sollen 4) Sicher, du kannst weiterhin von stdin lesen, aber du wirst immer EOF bekommen. Wenn Sie nicht zustimmen, geben Sie bitte eine Illustration an. – Chris

+0

Entschuldigung, bei meiner eigenen Recherche scheint es, dass du auch bei 4 recht hast. Vielen Dank. – Chris

0

Zuerst wird, wie bereits erwähnt, müssen Sie% lf statt d von% der Doppel angezeigt werden, sonst wird es zeigen nur Null die ganze Zeit (d für eine ganze Zahl mit Vorzeichen ist). Wenn Sie dies manuell auf einem Windows-basierten Betriebssystemtyp in einigen Zeichen testen möchten, drücken Sie die EINGABETASTE und dann STRGZ in der nächsten Zeile ganz von selbst (dies simuliert das EOF).Das Druckergebnis wird um eins mehr als die Anzahl der Zeichen (es enthält die CtrlZ). Auch wenn SoapBox bei der Suche nach einem EOF angezeigt wurde, war das Denken damals meist Unix, wo man eine Datei über Standardeingabe in das Programm pipete, das würde auch funktionieren.

Verwandte Themen