ifstream | letzter Buchstabe doppelt
-
Ich möchte aus der ".txt" Datei "test.text" den Inhalt auslesen. Inhalt = Horst.
Ich hätte das dann folgendermaßen gemacht:#include <iostream> #include <fstream> using namespace std; int main() { char a; ifstream File; File.open("D:/test.txt", ios::in); while(!File.eof()) { File >> a; cout << a; } cout << "\n"; return 0; }Mein Problem, es wird zwar was ausgelesen, aber es wird "Horstt" ausgelsen, was soll das 2te "t" da? Irgendwas mach ich noch n bissel falsch irgendwie....
MfG
StrombergPS: Wenn wir schon mal dabei sind, was ich bis jetzt immer noch nicht so ganz gecheckt habe, warum ist "ofstream" eigentlich für auf die Festplatte schreiben, und "ifstream" für von der Festplatte lesen??? Also ich mein jetzt vom Namen her, weil es würde doch viel mehr passen wenn "ofstream" fürs lesen zuständig wäre (output -> raus), und "ifstream" fürs schreiben (input -> rein)....oder hat das nen tieferen Hintergrund den ich noch nicht verstehe?
-
Hi Stromberg,
afaik wird das eofbit erst gesetzt, wenn das Ende der Datei erreicht wurde.
Du fragst also:
Ist das eof flag gesetzt und ließt dann den nächsten Buchstaben.
Du mußt aber fragen, ob die Leseoperation erfolgreich war, bevor du sie auswertest.
Du hast jetzt beispielsweise das letzte Zeichen gelesen.
Dann merkt er, dass er das Zeichen noch lesen konnte und setzt das flag
folglich noch nicht. Beim nächsten Versuch sagt er dann, den Buchstaben
kann ich nicht mehr lesen -> eof.
Das bit ist ein feedback auf die letzte Leseoperation und keine Aussage
über die nächste Leseoperation.wegen der Namensgebung ifstream und ofstream:
Sieh es aus der Sicht deines Programmes. Ins Programm rein, aus dem Programm raus.Gruß,
CSpille
-
Mh, verstanden hab ich das Problem jetzt schon, er reagiert nicht darauf, dass er den letzten Bcuhstaben gelesen hat, sondern er reagiert darauf wenn er merkt das kein Buchstabe mehr da ist, und es halt leer ist.
Aber wie ich das Problem lösen kann hab ich nicht so ganz verstanden?
Ich kann natürlich jetzt bei jedem Wort immer den letzten Buchstaben abschneiden, aber ob das eine so glorreiche Idee ist bezweifle ich oder? Da gibts doch sicher was besseres....
MfG
Stromberg
-
Nach dem Lesen mußt du abfragen, ob du die Daten noch verarbeiten kannst:
while(!File.eof()) { File >> a; if(!File.eof()) cout << a; }oder eleganter:
#include <iostream> #include <fstream> using namespace std; int main() { char a; ifstream File; File.open("D:/test.txt", ios::in); File >> a; while(!File.eof()) { cout << a; File >> a; } cout << "\n"; return 0; }Gruß,
CSpille
-
Den Status des Streams kannst du einfach mit dem impliziten (void
Operator testen:while(File) // <- istream::operator void*() { File >> c; }Die Abfrage auf eof() ist nicht so gut, da es noch andere Fehlerzustände gibt, welche dann nicht getestet würden und du eine Endlosschleife hättest...
-
Th schrieb:
Den Status des Streams kannst du einfach mit dem impliziten (void
Operator testen:while(File) // <- istream::operator void*() { File >> c; }Die Abfrage auf eof() ist nicht so gut, da es noch andere Fehlerzustände gibt, welche dann nicht getestet würden und du eine Endlosschleife hättest...
Cool...
Die Abfrage mit dem impliziten (void
operator kannte ich auch noch nicht.
Dass andere Fehler existieren können (failbit, badbit), war mir klar.
Ehrlich gesagt hab ich diese aber bisher immer ignoriert ^^, da sie sehr selten
auftreten und man ja schreibfaul ist
EDIT: btw: Ich hätte ja schon immer einfach good() abfragen können.Danke für den interessanten Hinweis
-
Dann ists so wohl am besten:
#include <iostream> #include <fstream> using namespace std; int main() { char a; ifstream File; File.open("D:/test.txt", ios::in); File >> a; //Nur die Zeile hier finde ich noch irgendwie hässlich, gibts keine Möglichkeit dass man alles in die Schleife bekommt? while(File) { cout << a; File >> a; } cout << "\n"; return 0; }MfG
Stromberg
-
Hallo Stromberg,
es gibt immer mehrere Möglichkeiten.
int main() { char a; ifstream File; File.open("D:/test.txt", ios::in); while(true) { File >> a; if(!File) break; cout << a; } cout << "\n"; return 0; }Diese Variante mit break finde ich persönlich nicht schön.
Oder wie gesagt die doppelte Überprüfung (bei Bedarf mit Status-Speicherung)int main() { char a; ifstream File; File.open("D:/test.txt", ios::in); bool state = true; while(state) { File >> a; state = File; if(state) cout << a; } cout << "\n"; return 0; }Welche Variante man bevorzugt ist natürlich Geschmacksache.
Ich denke allerdings nicht, dass du an zwei Leseoperationen, zwei eof-Prüfungen
oder einem break vorbeikommst.Gruß,
CSpille
-
Also noch mal in Kürze.
Es reicht folgende Schleife:while(File >> c) // <- istream::operator void*() { cout << c; }Da jedoch der >>-Operator standardmäßig Leerzeichen überliest, sollte man dann doch besser get() benutzen (um die Zeichen 1:1 zu kopieren):
while(c = File.get(), File) { cout << c; }Alternativ kann man auch zeilenweise mit getline(...) in einen std::string lesen.
-
Und für die, die das alles zu blöde finden:
#include <fstream> #include <iostream> #include <algorithm> #include <iterator> int main() { std::ifstream file_stream("D:\\test.txt"); if (!file_stream) { std::cerr << "FEHLER: Datei konnte nicht geöffnet werden!" << std::endl; return 1; } std::copy(std::istream_iterator<char>(file_stream), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout, ""); }
-
warum endl?

-
rdbuf()