Über IStream einlesen und sortieren



  • DaDaUrka schrieb:

    Das mit String kann ich mir vorstellen, hallte ich jedoch für sehr umständlich, die PersonenDaten sind alles char-Arrays. Das müsste ich dann wieder kopieren usw.

    Das macht nichts. Am besten wäre es aber wenn du von Anfang an überall std::string hättest.

    /*
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    */
    ifstream file("testo.txt");
    
    string textFile = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>());
    replace(textFile.begin(),textFile.end(),',',' ');
    
    istringstream newFile(textFile);
    
    PersonenListenElement a; feed(newFile,&a);
    

    Frage an die Experten:
    Wieso funktionier das nur so:

    string textFile = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>());
    

    und nicht so:

    string textFile(istreambuf_iterator<char>(file), istreambuf_iterator<char>());
    

    ???



  • KasF schrieb:

    Preisfrage an die Experten:
    Wieso funktionier das nur so:

    string textFile = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>());
    

    und nicht so:

    string textFile(istreambuf_iterator<char>(file), istreambuf_iterator<char>());
    

    ???

    http://www.gotw.ca/gotw/075.htm - reicht das als Antwort?



  • CStoll schrieb:

    http://www.gotw.ca/gotw/075.htm

    Danke 👍
    ( Kam vllt so rüber als ob ich das wüsste und euch testen wollte, aber dem war/ist nicht so :), habe mich nur gewundert wieso das nicht funktionierte )



  • Ich will jetzt nicht faul rüberkommen, aber der Testtreiber funzt wunderbar. Und will jetzt nicht alles auf string umschreiben. Zudem war es ja in der Aufgabenstellung gewollt, über iostreams ein-/auszulesen.

    Ich werde mal am we das mal zeichenweise probieren.



  • DaDaUrka schrieb:

    Zudem war es ja in der Aufgabenstellung gewollt, über iostreams ein-/auszulesen.

    Was hat das eine mit dem anderen zu tun? char-Arrays sind Relikte aus C, in C++ kommst du mit std::string wesentlich schneller und einfacher zum Ziel als mit manuellen char*-Manipulationen.



  • Du musst auch nicht alles auf string umschreiben, eher gesagt gar nichts. Deine Struktur kann noch normal mit char* aufgaubt sein.

    Aber machs lieber dann zeichenweise, damit sich dein Prof nicht wundert, woher du sowas zusammen gekratzt hast. Zeichenweise sollte auch nicht schwer sein. Einfach bei Problemen hier wieder fragen 😉



  • Also ich habe jetzt folgendes probiert:

    void PersonenListe::feed (istream & rein, PersonenListenElement * ple){
    
            char buffer('\0');
    
            int i(0);
            while(1){
                    rein.get(buffer);
                    if(isalnum(buffer)) break;
            }
    
            ple->person.Nachname[0] = buffer;       // Erstes Zeichen auf Nachname schieben 
            i=1;                                    // i auf 1 damit beim 2. Zeichen von Nachnae anschliesst
    
            while(1){
                    rein.get(buffer);
    
                    // Nachname bis Whitespace oder , einlesen 
                    if(isalnum(buffer)){
                            ple->person.Nachname[i] = buffer;
                            i++;
                    }else break;
            }
    
            while(1){
                    rein.get(buffer);               // Zum Vornamen springen
                    if(isalnum(buffer))break;
            }
    
            ple->person.Vorname[0]=buffer;          // Erstes Zeichen in Vornamen schieben
            i=1;                                    // i auf 1 damit beim 2. Zeichen von Vorname anschliesst
    
            while(1){
                    rein.get(buffer);
    
                    // Vorname bis Whiitespace oder , einlesen 
                    if(isalnum(buffer)){
                            ple->person.Vorname[i] = buffer;
                            i++;
                    }else break;
            }
    
            while(1){
                    rein.get(buffer);
                    if(isalnum(buffer))break;
            }                                       // Zum Geburstdatum springen
    
            ple->person.Geburtsdatum[0]=buffer;     // Erstes Zeichen in Geburtsdatum schieben
            i=1;                                    // i auf 1 damit beim 2. Zeichen von Geburtsdatum anschliesst
    
            while(1){
                    rein.get(buffer);
    
                    // Geburtsdatum einlesen 
                    // Hier ist auch schon der Knackpunkt:
                    // Der Istream schmeißt immer irgendeinen Mist noch hinten an das datum dran. Wieso?
                    // Der DDD zeigt manchmal ein P bzw.A an ich glaube der will den Line Feed als char 
                    // noch akzeptieren und übersetzt ihn in ein Zeichen!?
                    if(buffer>='0' && buffer <='9' || buffer == '.'){
                            ple->person.Geburtsdatum[i] = buffer;
                            i++;
                    }else break;
            }
    }
    

    Das funzt auch alles soweit, jedoch schmeißt mir das Programm hinten an den Geburtstag noch den Line Feed glaube dran und übersetzt das Zeichen.
    Deswegen sieht die Ausgabe so aus:

    Bei einem Block:

    ----- Ausgabe -----
    Max, Schmidt, 25.06.1986������,
    

    Bei mehr Blöcken:

    ----- Ausgabe -----
    Max, Schmidt, 25.06.1986������A,
    Britta��������, Prause, 12.11.1987,
    

    Was könnte das sein?



  • Uiuiui, dein Code sieht nicht gerade sicher und auch sauber aus, aber egal wenn man so frickelt lernt man eh am besten 😉

    Das Problem kommt daher, dass du deine char*'s nicht mit einer 0 abschließst.

    Beispiel beim ersten:

    while(1){
                    rein.get(buffer);
    
                    // Nachname bis Whitespace oder , einlesen
                    if(isalnum(buffer)){
                            ple->person.Nachname[i] = buffer;
                            i++;
                    }else break;
            }
    ple->person.Nachname[i] = 0; // Zeichenkette abschließen
    

    Bei den anderen dann auch ...



  • mhhh okay.

    Ich nehme an manuell eine terminierende Null selbst rein machen wäre Stümper haft... 😃



  • Topic mehr oder weniger gelöst:

    Hab ganz vergessen noch meinen letzten Stand zu posten.

    void PersonenListe::feed (istream & rein, PersonenListenElement * ple){
    	// Eine unelegante aber robuste Art(glaube ich zumindest) einzulesen
    	// Fuer Vorschlaege bin ich sehr offen. :-)
    
    	// Ueberschreibe alle Werte, weil er sonst Mist reinschreibt
    	for(int j=0;j<=20;j++){
    		ple->person.Nachname[j]='\0';
    	}
      	for(int j=0;j<=20;j++){
    		ple->person.Vorname[j]='\0';
    	}
      	for(int j=0;j<=11;j++){
    		ple->person.Geburtsdatum[j]='\0';
    	}
    
     	char buffer('\0');
    
    	int i(0);
    	while(1){
    		rein.get(buffer);
    		if(isalnum(buffer)) break;
    	}
    
    	ple->person.Nachname[0] = buffer;	// Erstes Zeichen auf Nachname schieben	
    	i=1;					// i auf 1 damit beim 2. Zeichen von Nachnae anschliesst
    
    	while(1){
    		rein.get(buffer);
    		// Nachname bis Whitespace oder , einlesen 
    		if(isalnum(buffer)){
    			if(i==20){break; cerr << endl << "Nachname zu lang." << endl;}
    			ple->person.Nachname[i] = buffer;
    			i++;				
    		}else break;
    	}
    
    	while(1){
    		rein.get(buffer); 		// Zum Vornamen springen
    		if(isalnum(buffer))break;
    	}
    
    	ple->person.Vorname[0]=buffer;		// Erstes Zeichen in Vornamen schieben
    	i=1;					// i auf 1 damit beim 2. Zeichen von Vorname anschliesst
    
    	while(1){
    		rein.get(buffer);
    
    		// Vorname bis Whiitespace oder , einlesen 
    		if(isalnum(buffer)){ 
    			if(i==20){break; cerr << endl << "Vorname zu lang." << endl;}
    			ple->person.Vorname[i] = buffer;
    			i++;
    		}else break;
    	}
    
    	while(1){
    		rein.get(buffer);
    		if(isalnum(buffer))break;
    	}					// Zum Geburstdatum springen
    
    	ple->person.Geburtsdatum[0]=buffer;	// Erstes Zeichen in Geburtsdatum schieben
    	i=1;					// i auf 1 damit beim 2. Zeichen von Geburtsdatum anschliesst
    
    //	ple->person.Geburtsdatum[11]='\0';	// Der schreibt immer einen Mist hinten rein, vielleicht weil Person explizit nicht intialisiert ist!?
    
    	while(1){
    		rein.get(buffer);
    
    		// Geburtsdatum einlesen 
    		if(buffer>='0' && buffer <='9' || buffer == '.'){ 
    			if(i==11){break; cerr << endl << "Geburtsdatum zu lang." << endl;}
    			ple->person.Geburtsdatum[i] = buffer;
    			i++;
    		}else break;
    	}
    }
    

    Funzt soweit auch. Wie gesagt, sieht nicht grad toll aus, aber es klappt. In einem Jahr lache ich darüber, oder weine... 😉


Anmelden zum Antworten