Dateibearbeitung mit "ifstream" - In Funktion auslagern (Zeigerproblem)



  • Hallo zusammen,

    ich habe wieder ein kleines Verständnisproblem mit Zeigern.

    Ich schreibe mir gerade einen ModelLoader-Klasse mit der ich später Models für OpenGL laden kann. Ich habe zuerst die dazugehörige Funktion einfach runtergeschrieben mit sich wiederholendem Code. Wo die Hauptfunktion nun funktioniert wollte ich ein Paar sich wiederholende Codeabschnitt in eine Funktion packen. Hier ist mein Problem.

    Ich öffne eine Datei mit ifstream. Danach prüfe ich wie viele Vertices ich in einer Datei habe mit folgendem Code:

    while(!ifs.eof())
    	{
    		string line;
    		getline(ifs, line);
    
    		if(line.find("v  ") != string::npos)
    			verticesCount++;
    	}
    
    	vertices = new GLfloat[verticesCount*3];
    	verticesCount = 0;
    
    	ifs.clear();
    	ifs.seekg(0, ios::beg);
    

    Das ganze möchte ich jetzt gerne in eine private Klassenfunktion auslagern. Das bekomme ich leider nicht hin. Hier mein Ansatz:

    int ModelLoader::count(ifstream *ifs, string s)
    {
    	int counter = 0;
    
    	while(!ifs->eof())
    	{
    		string line;
    		getline(*ifs, line);
    
    		if(line.find(s.c_str()) != string::npos)
    			counter++;
    	}
    
    	ifs->clear();
    	ifs->seekg(0, ios::beg);
    
    	return counter;
    }
    

    Das merkwürdige ist, das ich das Programm im Debug-Modus ausführen kann, jedoch das Model fehlerhaft ist.

    Vll. ist aber mein Ansatz auch komplett falsch alles mit Zeigern zu lösen.

    Wenn ich es nämlich ohne Zeiger, mit einfacher Parameterübergabe versuche bekomme ich folgende Fehlermeldung.

    error C2248: "std::basic_ios<_Elem,_Traits>::basic_ios": Kein Zugriff auf private Member, dessen Deklaration in der std::basic_ios<_Elem,_Traits>-Klasse erfolgte.
    1>          with
    1>          [
    1>              _Elem=char,
    1>              _Traits=std::char_traits<char>
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(176): Siehe Deklaration von 'std::basic_ios<_Elem,_Traits>::basic_ios'
    1>          with
    1>          [
    1>              _Elem=char,
    1>              _Traits=std::char_traits<char>
    1>          ]
    1>          Diese Diagnose trat in der vom Compiler generierten Funktion "std::basic_ifstream<_Elem,_Traits>::basic_ifstream(const std::basic_ifstream<_Elem,_Traits> &)" auf.
    1>          with
    1>          [
    1>              _Elem=char,
    1>              _Traits=std::char_traits<char>
    1>          ]
    


  • OK, habs selber hinbekommen 🙂

    int ModelLoader::count(ifstream &ifs, string s)
    {
    	int counter = 0;
    
    	while(!ifs.eof())
    	{
    		string line;
    		getline(ifs, line);
    
    		if(line.find(s.c_str()) != string::npos)
    			counter++;
    	}
    
    	ifs.clear();
    	ifs.seekg(0, ios::beg);
    
    	return counter;
    }
    


  • Der Schleifenkörper von while(!eof()){ ... } wird einmal mehr ausgeführt als Zeilen da sind.
    Bewährt hat sich ein anderes Idiom.(s.u.).

    Z.B. siehst Du in der Ausgabe dieses Programms eine Leerzeile vor "</Test1>":

    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main(){
      using namespace std;
      const string filename{"./test.cc"};  // test.cc ist dieser source
      cout << "<Test1>\n";
      {
        ifstream stream{filename};
        while(!stream.eof()){
          string s;
          getline(stream, s);
          cout << s << '\n';
        }
      }
      cout << "</Test1>\n<Test2>\n";
      {
        ifstream stream{filename};
        for(string s; getline(stream, s);)
          cout << s << '\n';
      }
      cout << "</Test2>\n";
    }
    

Anmelden zum Antworten