gesamtes file einlesen und in liste speichern



  • Ich möchte ein 40 MB grosses file einlesen und in einer Liste abspeichern.
    Hier mein Versuch, das einlesen in stream ist falsch. Und das Speichern in die Liste funktioniert nicht.

    readin (const char* testfile ) {
    
    	int i,j;
    
    	fileisopen=false;
    	outfileisopen=false;
    	FILE * file = new File( testfile );
    	stream= new Stream( file );
    
    	fileisopen=file->open( ReadOnly );
    
    	numlines=0;
    	if ( fileisopen) {
    
    			stream->device()->reset();
    			while ( !stream->atEnd() ) {
    				list.append(stream->readLine()); 			}
    
    			numlines=linelist.count();
    			printf("%d lines read\n",numlines);
    	}
    
    	file->close();
    	it = linelist.begin();
    

    bin für jede Hilfe dankbar..



  • Was für eine API ist das? Unter C++ funktioniert das anders. Außerdem sind da auch Fehler drin.

    void readin(string const& filename)
    {
        ifstream ifs(filename.c_str());
    
        if (not ifs) return;
    
        string line;
        while (getline(ifs, line))
            list.push_back(line);
    
        it = list.begin();
    }
    


  • Benutze einen Vector, der reicht völlig.

    vectorname.push_back(datei.getline(...));
    

    und zugriff dann normal per index:
    vectorname[zeile];

    Bedenke, das ein Vector sich nur soweit erweitert, wie Arbeitsspeicher zur Verfuegung steht. Solltest du keine 40MB mehr frei haben, funktioniert deine logik nicht.



  • Wenn du unbedingt mit FILE's arbeiten willst, musst du auch die C-IO-Funktionen (fopen, fgets,...) verwenden. Aber besser ist es, du verwendest fstreams.
    (und schaust dir ein Tutorial an, wie man damit umgehen kann)



  • Erstmal vielen Dank. Ich hatte eine Bibliotek mit c++ Funktionen vermischt.

    Leider hane ich immer noch Probleme das File in den Vektor einzulesen.
    Also ich habe jetzt zur Vereinfachung alles in main:

    #include<cstdlib>
    #include<fstream>
    #include<iostream>
    #include<vector>
    #include<string>
    using namespace std;
    
    int main() {
    
    vector <string> v1;
    int x,y;
    
       //ifstream ifs(filename.c_str()); //öffne angegebenes File
    
        ifstream quelle;
        quelle.open("test.PC"); //ist ascii datei
        if (!quelle) {
            cerr << "Datei kann nicht geöffnet werden!\n";
            exit(-1);
        }
        string line; 
        while (!quelle.eof()) {
           v1.push_back(quelle.getline(line, sizeof(line)));
        /*hier error C2664: 'class std::basic_istream<char,struct std::char_traits<char> > &__thiscall std::basic_istream<char,struct std::char_traits<char> >::getline(char *,int)' : Konvertierung des Parameters 1 
    von 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' in 'char *' nicht moeglich*/
    
        f.close();
    
        quelle.close();  
    
        cin.get();   // Eingabe von RETURN beendet das Programm
    }   // automatisches {\tt close()}
    

    desweiteren möchte ich nicht alles aus dem file auslesen(ist 40 mb gross), sondern nur bestimmte Sequenzen.

    das file ist so aufgebaut, dass am Anfang jeder Zeile zu erkennen ist zu welcher Kategorie und Unterkategorie die Zeileninhalte gehören.
    z.B. SEURPNLDZALD, brauche ich das 4.Zeichen(bei 0 angefangen) als Indikator welche Oberkategorie und das 12.Zeichen als Indikator welche Unterkategorie.
    mein Versuch:

    int i,j;
    int sec;
    int subsec;
    	//*** initialize extract  *********
    	for(i=0;i<=7;i++){            //Kategorie
    		for(j=0;j<=15;j++){  //Unterkategorie
    			string extract[i][j]=0; //hier Fehler weil keine Konstanten.  ?? ich möchte das array dynamisch befüllen. Bzw. hier mit 0 initilisieren
    
    			//********** which section**************
    
    				if(quelle.seekg(4) == 'A')	{
    						sec=1;	
    				}
    				else if(quelle.seekg(4)=='D') sec=2;
    				else ifquelle.seekg(4)=='E') sec=2;
    				//usw.
    				else{
    					it++;
    					return(1);
    				}
    
    			//******** section wanted?****************
    
    				w=0;
    				for(i=0;i<15;i++){
    
    					w=w+extract[sec-1][i];
    				}
    
    				if(w==0){
    					it++;
    					return(1);
    				}
    
    			//********	which subsection **************+	
    
    				switch (sec){
    
    					case 1://brauche ich nicht
    
    						break;
    
    					case 2: //brauche ich											
    						if((quelle.seekg(12).isSpace()) subsec;=0;				
    						else if(quelle.seekg(12)=='B') subsec=1;
    						else{
    							it++; 
    							return(1);
    						}
    

    Ist das von der Logik her richtig. Nun ja, ich hoffe meine Beschreibung ist überhaupt zu verstehen.



  • Erstmal: getline() liefert nicht den gelesenen String zurück, sondern den Stream(status).

    Zweitens: Die istream-Methode getline() arbeitet auf char-Arrays, besser ist die globale Funktion getline() (die verwendet std::string).

    Damit klappt das Einlesen eher so:

    ifstream quelle("test.PC");
    string zeile;
    while(getline(quelle,zeile))
    {
      vl.push_back(zeile);
      //wenn du die Eingabezeilen auswerten willst, ist hier vermutlich der richtige Platz dafür
    }
    


  • Danke!
    Einlesen funkt nun.


Anmelden zum Antworten