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++ ?





  • 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.


Anmelden zum Antworten