Problem bei Ifstream
-
Ich versuche folgendes zu machen :
1. Mit ifstream eine Datei öffnen.
2. Durchzählen wieviele Zeichen drinn sind.
3. Speicher reserviren für die anzahl der gezählten Zeichen.
4. Datei in diesen Reservierten Speicher lesen.Ich habe jetzt aber das Problem, das beim 2. mal lesen der Datei nur Müll zurückgelesen wird. Beim ersten mal wird die Datei super eingelesen, aber das 2. mal geht gar nix.
Ich hänge mal meinen Code an, vielleicht weiß ja jemand was es sein könnte. Ich bin noch sehr neu in c++ Filehandling.
char ch; int x,y,z,i; ifstream in(filename); x = 0; y = 0; z = 0; if(!in.is_open()) { cerr << "map::File " << filename <<" could not be opened !!"; exit(1); } // First lets count, how many memory we need for the file while (!in.eof()) { ch=in.get(); if (ch == 10) { y++; //count lines } else { x++; //count pieces } if(ch == 32) // count spaces { z++; } } x = x - 1; // subtract last char, because of 1 loop too much this->lines = y; // store the needed values this->mapsize = x; // store the needed values char *mapdata = new char[x]; // Reservate enough memory for the mapdata ifstream inn(filename); cout << inn.tellg(); in.seekg (0, ios::beg); cout << inn.tellg(); if(!in.is_open()) { cerr << "map::File " << filename <<" could not be opened !!"; exit(1); } while (!in.eof()) { ch=in.get(); *mapdata = ch; mapdata++; } in.close(); for (i = 0; i <= this->mapsize; i++) { if(!(i %(this->mapsize / this->lines))) { cout << endl; } else { cout << *mapdata; } mapdata++; }Hier wird beim 2. mal while (!inn.eof()) anscheinend nichts oder nur Müll gelesen. Keine Ahnung warum !
-
1. Fehler:
Wenn der Stream nicht im good-Zustand ist, macht das seekg genau garnichts. Weil er zumindest zu dem Zeitpunkt wo du mit dem Lesen fertig bist das eof-Bit gesetzt hat, macht das seekg garnichts. Also: mit .clear() den Fehlerstatus zurücksetzen.
2. Fehler:
while (!inn.eof()) { ch=in.get(); *mapdata = ch; mapdata++; }Nachdem du mit get gelesen hast, musst du auf eof prüfen. Du verarbeitest das Zeichen aber einfach. Zudem liefert in.get() einen int zurück und keinen char. D.h. im eof-Fall hast du hier z.B. einen Informationsverlust. Du musst hier mit den Traits arbeiten, um das Zeichen korrekt auf Fehler zu prüfen und dann in einen char zu wandeln.
-
Kannst du mir vielleicht nen link geben, wo es ein tutorial oder so gibt für Filehandling mit c++ ?
-
Schau erstmal in die C++-FAQ:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39469.htmlFalls dir das noch nicht ausreicht, schau mal hier:
http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=eof#Answ
-
Danke !
-
Tom555 schrieb:
Ich versuche folgendes zu machen :
1. Mit ifstream eine Datei öffnen.
2. Durchzählen wieviele Zeichen drinn sind.
3. Speicher reserviren für die anzahl der gezählten Zeichen.
4. Datei in diesen Reservierten Speicher lesen.Also so
#include <algorithm> // copy, distance #include <fstream> #include <iterator> // istreambuf_iterator int main() { using namespace std; const int anz = distance( istreambuf_iterator< char >( ifstream( "input.txt" ).rdbuf() ), istreambuf_iterator< char >() ); char* mapdata = new char[anz]; // besser boost::shared_array copy( istreambuf_iterator< char >( ifstream( "input.txt" ).rdbuf() ), istreambuf_iterator< char >(), mapdata ); delete[] mapdata; return 0; }noch einfacher wäre es, wenn Du es so machst:
#include <algorithm> // copy #include <fstream> #include <iterator> // istreambuf_iterator, back_inserter #include <vector> int main() { using namespace std; vector< char > mapdata; copy( istreambuf_iterator< char >( ifstream( "input.txt" ).rdbuf() ), istreambuf_iterator< char >(), back_inserter( mapdata ) ); char* mapdata2 = &mapdata[0]; // zeigt auf den Anfang des reservierten Speichers const int anz = mapdata.size(); // Anzahl der Zeichen return 0; }Gruß
Werner
-
@werner
Cool, danke. Das werd ich morgen gleich mal ausprobieren.