Verständnisfrage EOF
-
Hallo,
ich hab aus einem Lehrbuch folgenden Code für ein Programm:
// switch3.cpp
#include<iostream>
using namespace std;int main(void){
int ch;while((ch=cin.get()) != EOF){
switch (char(ch)){
case '$':
cout << "nen dollarzeichen! \n ";
break;
case '%':
cout << "nen prozentzeichen! \n ";
break;
default:
cout << char (ch);
}
}
system("Pause");
return 0;
}Darüber, was das Programm macht bin ich mir relativ im Klaren, allerdings verstehe ich eins nicht ; und zwar die Abfrage der While Schleife:
while((ch=cin.get()) != EOF){
EOF heisst ja End of File. Hiermit kann ich aber nichts anfangen. cin.get(); wirft mir ja den ASCII Code für das Zeichen aus, welches ich eingebe oder?
Nur verstehe ich nicht, in welcher Weise sich hier EOF auswirkt und wie es funktionert.
Es wäre Nett wenn mir hier jemand helfen könnte
-
Buch löschen.
-
Zackorz schrieb:
Nur verstehe ich nicht, in welcher Weise sich hier EOF auswirkt und wie es funktionert.
Ganz einfach, sobald du EOF eingibst bricht die Schleife ab.
-
Ja, das ist klar, aber EOF hat da doch ne höhere Bedeutung oder?
Welche Funktion erfüllt EOF allgemein, wofür steht es?
Sonst hätte man ja auch !=wurst schreiben können, hier steckt schon ein Sinn dahinter.
-
volkard schrieb:
Buch löschen.
Ja, vergiss am Besten dieses Programm vollständig, es beruht in seiner Funktion auf Relikten aus längst vergangenen Zeiten. Der Rest des Buches ist dann bestimmt nicht besser. Dein Beispielprogramm sollte man besser so umschreiben:
#include<iostream> using namespace std; int main(){ // Entweder int main() oder int main(int, char* []) // int(void) ist kein legales C++ char ch; // Wir wollen Zeichen, keine ints while(cin.get(ch)){ // EOF ist in C++ ein Zustand, kein Zeichen. Ein istream wird zu false ausgewertet, wenn EOF erreicht ist oder ein anderer Fehler auftritt. switch (ch){ // Der Cast ist nun nicht mehr nötig. Genaugenommen war er es auch vorher nicht, da int und char zueinander eine Standardkonvertierung haben case '$': cout << "nen dollarzeichen! \n "; break; case '%': cout << "nen prozentzeichen! \n "; break; default: cout << ch; // Siehe oben } } // system("Pause"); Das ist hochgradig betriebssystemabhängig. Und gerade in einem Programm wie diesem macht es ja überhaupt keinen Sinn noch zu warten, wenn das Ende der Eingabe erreicht ist. return 0; }
-
Habs auch gerade getestet, bei der Eingabe von EOF passiert garnichts, die Schleife läuft normal weiter.
-
SeppJ schrieb:
// int(void) ist kein legales C++
Doch.
Das
void
ist in C++ nicht mehr nötig, aber erlaubt. Es entspricht einer leeren Parameterliste. Im Gegensatz zu C, wo eine leere Parameterliste gleichbedeutend mit variablen Argumenten ist.
-
Wenn du Windows benutzt drück mal STRG + Z. Das ist EOF auf der Konsole.
-
OK, danke SeppJ.
Das system("Pause") steht auch so nicht dabei, allerdings schliesst sich bei mir unter Windows XP ansonsten das Fenster so schnell, dass ich keine Ausgabe sehen kann.
Kannst du mir noch ein bisschen genauer erklären was es mit EOF auf sich hat?
Wann wird EOF erreicht, was muss hierzu eintreten?
-
Zackorz schrieb:
...viele Fragen zu EOF...
Der Code beruht darauf, dass in irgendeiner C Bibliothek ein Makro namens EOF (End-Of-File) definiert ist. Dieses hat normalerweise einen Wert wie z.B. -1 der garantiert nicht der ASCII Wert eines anderen Zeichens ist. Wenn ein Datenstrom zuende ist, dann hat das zuletzt gelesene Zeichen den Wert von diesem EOF.
Das hat bei antiken Dateisystemen mal Sinn gemacht, EOF als Zeichen zu betrachten. C++ behandelt Ein-/Ausgabe jedoch abstrakter und EOF als Zeichen sollte nicht mehr verwendet werden. Man sollte lieber nach dem Lesen prüfen, ob ein Eingabestrom noch 'good()' ist.
-
SeppJ schrieb:
Das hat bei antiken Dateisystemen mal Sinn gemacht, EOF als Zeichen zu betrachten. C++ behandelt Ein-/Ausgabe jedoch abstrakter und EOF als Zeichen sollte nicht mehr verwendet werden. Man sollte lieber nach dem Lesen prüfen, ob ein Eingabestrom noch 'good()' ist.
Ich glaube, das C ist da abstrakter, während C++ mit good() oder eof() konkret bescheid sagt.
Auch glaube ich nicht, daß das an antiken Dateisystemen lag, sondern an den unglaublichen Preisen für Funktionsaufrufe.
-
Vielen Dank für die schnelle Hilfe, also ist EOF ledigleich eine Überprüfung, dass kein nicht-ASCII Zeichen und kein Fehler stattgefunden hat, oder?
-
Die Schleife läuft hier solange kein Fehler entsteht unendlich oder?
-
volkard schrieb:
Auch glaube ich nicht, daß das an antiken Dateisystemen lag, sondern an den unglaublichen Preisen für Funktionsaufrufe.
Doch wirklich: Beim CP/M Dateisystem gab es tatsächlich EOF als ASCII Zeichen (glaube Code 26 oder so), weil das Dateisystem es mit der Dateilänge nicht so genau nahm. Bei MS_DOS gab es das dann auch noch zumindest für Textdateien, aus Gründen der Abwärtskompatibilität, obwohl es eigentlich unnötig geworden war. Heutzutage wird das aber soweit ich weiß nirgends mehr verwendet, deswegen dieses Gehacke mit EOF=-1
-
Zackorz schrieb:
Vielen Dank für die schnelle Hilfe, also ist EOF ledigleich eine Überprüfung, dass kein nicht-ASCII Zeichen und kein Fehler stattgefunden hat, oder?
Nein, EOF heißt EndOfFile. Und ist in C üblich. In C++ nicht.
http://www.cplusplus.com/reference/iostream/istream/get/
Da steht nix von EOF bei get() und einem Dateiende."In ISO-C können Datei- und IO-Operationen einen Wert zurückgeben, der dem symbolischen EOF entspricht und damit anzeigt, dass das Ende erreicht wurde. Der tatsächliche Wert beträgt häufig −1, ist allerdings systemabhängig."
-
Zackorz schrieb:
Die Schleife läuft hier solange kein Fehler entsteht unendlich oder?
Sie läuft, bis der Eingabestrom zuende ist. Unter POSIX-Systemen kann man dies mit ctrl+D an der Tastatur simulieren, für Windows gibt es hier eine Übersicht:
http://www.fredosaurus.com/notes-cpp/io/eof.html
-
OK, wie das Ende eines Datenstroms ohne den Ctr+Z+Enter Befehl zustande kommen kann weiss ich zwar noch nicht, wird aber sicher noch irgendwann später in der Programmierung gezeigt werden. (Im Code ist ja anscheinend keine Bedingung eingebaut, die sagt wann ein Datenstrom beendet ist, es kann immer wieder neu eingegeben werden).
Alle anderen Fragen wurden beantwortet, vielen Dank an Alle :_)
-
SeppJ schrieb:
volkard schrieb:
Auch glaube ich nicht, daß das an antiken Dateisystemen lag, sondern an den unglaublichen Preisen für Funktionsaufrufe.
Doch wirklich: Beim CP/M Dateisystem gab es tatsächlich EOF als ASCII Zeichen (glaube Code 26 oder so), weil das Dateisystem es mit der Dateilänge nicht so genau nahm. Bei MS_DOS gab es das dann auch noch zumindest für Textdateien, aus Gründen der Abwärtskompatibilität, obwohl es eigentlich unnötig geworden war. Heutzutage wird das aber soweit ich weiß nirgends mehr verwendet, deswegen dieses Gehacke mit EOF=-1
Komisch.
Ich nehme an, Du beziehst Dich auf
http://www.answers.com/topic/end-of-file
Control+Z ist 26.
Aber getchar() von CP/M liefert beim Eingeben von Control-Z ein EOF(=-1). Siehe
http://www.cpm.z80.de/develop/cman.pdf
Seite 55.
-
volkard schrieb:
Komisch.
Ich nehme an, Du beziehst Dich auf
http://www.answers.com/topic/end-of-file
Control+Z ist 26.
Aber getchar() von CP/M liefert beim Eingeben von Control-Z ein EOF(=-1). Siehe
http://www.cpm.z80.de/develop/cman.pdf
Seite 55.Interessant, endlich mal gute Quellen dazu. Alles was ich oben geschrieben habe, war einfach so aus dem Kopf ohne Quellenrecherche, deshalb die Ungenauigkeiten. Zumindest die Idee, dass es früher ein echtes Zeichen war und das daher die C Syntax kommt, ist ja richtig.
Zackorz schrieb:
OK, wie das Ende eines Datenstroms ohne den Ctr+Z+Enter Befehl zustande kommen kann weiss ich zwar noch nicht, wird aber sicher noch irgendwann später in der Programmierung gezeigt werden.
Was spricht denn gegen ctrl+z/d? Das ist an der Tastatur eigentlich die einzige Möglichkeit. Wenn ein Strom mit einer Datei verbunden ist, ist EOF, wenn die Datei zuende ist und wenn er mit der Tastatur verbunden ist, ist EOF, wenn CTRL+Z/D gedrückt wird.
(Im Code ist ja anscheinend keine Bedingung eingebaut, die sagt wann ein Datenstrom beendet ist, es kann immer wieder neu eingegeben werden).
Doch, das while(cin.get(ch)) ist die Bedingung. cin.get() gibt den aufrufenden istream wieder zurück, in diesem Fall cin. Der Ausdruck in den Klammern nach dem while wird dann zu einem bool ausgewertet. Für einem istream wie cin heißt dass, das der Wert true ist, wenn alles in Ordnung ist und false, wenn etwas nicht stimmt, etwa das Ende der Datei erreicht ist.
-
SeppJ schrieb:
volkard schrieb:
Komisch.
Ich nehme an, Du beziehst Dich auf
http://www.answers.com/topic/end-of-file
Control+Z ist 26.
Aber getchar() von CP/M liefert beim Eingeben von Control-Z ein EOF(=-1). Siehe
http://www.cpm.z80.de/develop/cman.pdf
Seite 55.Interessant, endlich mal gute Quellen dazu. Alles was ich oben geschrieben habe, war einfach so aus dem Kopf ohne Quellenrecherche, deshalb die Ungenauigkeiten. Zumindest die Idee, dass es früher ein echtes Zeichen war und das daher die C Syntax kommt, ist ja richtig.
Eben nicht!
Die C-Syntax mit Returnwert -->> -1 <<-- bei getchar() ist im selben CP/M, wo man nur ganze Sektoren laden und speichern kann, wo man die Dateigröße nicht genau abfragen kann (Nur Anzahl der Sektoren), und wo man sich verabredet hat, Textdateien mit -->> 26 <<-- aufhören zu lassen. Daß die -1 nicht ein echtes Zeichen ist, steht eindeutig auf Seite 55. Hätte man die 26 als Dateiendezeichen im Auge gehabt, hätte man getchar() auch eine 26 zurückliefern lassen und hätte eine größere Einheitlichkeit gehabt. Aber EOF war nie 26, fürchte ich.