Zwei Dateien zeilenweise einlesen



  • Ich versuche zwei Dateien Zeilenweise auszulesen...
    Inhalt der Dateien...:
    *
    Vornamen.txt*
    Peter
    Dieter

    Nachnamen.txt
    Schmidt
    Bauer

    Ich öffne beide Dateien mit fstream im ios::in Modus.
    So lese ich die Dateien aus...:

    while(std::getline(vornamen, vname))
    {
    	while(std::getline(nachnamen, nname))
    	{
    		std::cout  << vname << " " << nname << std::endl;
    	}
    }
    

    Ausgegeben wird mir:
    Peter Schmidt
    Peter Bauer

    Ich möchte aber das mir ausgegeben wird:
    Peter Schmidt
    Peter Bauer
    Dieter Schmidt
    Dieter Bauer

    Wenn ich das ganze im Debugger verfolge durchläuft er sogar Dieter und dann die Nachnamen, ausgegeben wird es mir komischerweise nicht?! Was mache ich falsch?



  • while(std::getline(vornamen, vname) && std::getline(nachnamen, nname))
        std::cout << vname << " " << nname << '\n';
    


  • Du liest falsch.
    NAch dem ersten Schleifendurchgang ist der Dateizeiger von vornamen (komischer Name für einen Filestream, oder?) am Ende, d. h. vornamen.eof() == true und deswegen wird die innere Schleife kein zweites mal durchlaufen (weil der Cast zu bool ein false liefert).

    @Kellerautomat: Du hast nicht verstanden was er will.



  • Dann gibt er mir aber nur
    Peter Schmidt
    Dieter Bauer

    aus. Ich möchte aber das jeder Vorname mit jedem Nachnamen ausgegeben wird. Deswegen habe ich auch zwei while-Schleifen genommen.



  • @glanfaenger: Du musst die Datei mehrmals öffnen.

    std::fstream vornamen("vornamen.txt");
      for (std::string vorname; std::getline(vornamen, vorname);) {
        std::fstream nachnamen("nachnamen.txt");
        for (std::string nachname; std::getline(nachnamen, nachname);)
          std::cout << vorname << ' ' << nachname << '\n';
      }
    


  • ... oder die Leseposition mit nachnamen.seekg( 0, ios::beg ); wieder an den Anfang setzen.

    Effizienter:

    #include <vector>
    #include <string>
    #include <sstream>
    #include <iostream>
    
    int main()
    {
    	std::stringstream vornamen( "Peter\nDieter\n" ); // bei dir fstream
    	std::stringstream nachnamen( "Schmidt\nBauer\n" ); // bei dir fstream
    
    	std::vector< std::string > nachnamen_vec;
    	std::string name;
    	while( std::getline( nachnamen, name ) )
    		nachnamen_vec.push_back( name );
    
    	while( std::getline(vornamen, name ) ) {
    
    		for( auto it = nachnamen_vec.begin(); it != nachnamen_vec.end(); ++it ) {
    
    			std::cout << name << " " << *it << "\n";
    		}
    	}	
    }
    


  • Das ist alles Blödsinn (Edit: Swordfishs Lösung natürlich nicht). Erstmal braucht er einen ifstream . Zweitens sollte er die Nachnamen zuerst in ein Array einlesen.

    Das wäre eine Möglichkeit:

    #include <iostream>
    #include <vector>
    #include <iterator>
    #include <string>
    #include <fstream>
    
    int main()
    {
            std::ifstream name_file("vornamen.txt"),
                          surname_file("nachnamen.txt");
    
            std::vector<std::string> surnames{std::istream_iterator<std::string>(surname_file),
                                              std::istream_iterator<std::string>()};
    
            for(std::string str;std::getline(name_file, str);)
                for(size_t i = 0;i != surnames.size();++i)
                    std::cout << str << ' ' << surnames[i] << '\n';
    }
    


  • Wenn jemand "zu Guttenberg" heisst, stimmt die Lösung von Sone schon nicht mehr.



  • Danke für eure Hilfe, aber warum sollte ich denn die Namen erst in einen Vektor packen?



  • glanfaenger schrieb:

    Danke für eure Hilfe, aber warum sollte ich denn die Namen erst in einen Vektor packen?

    Weil es sau ineffizient ist die Datei nochmal und nochmal und nochmal zu durchlaufen. Da ist ein Array viel effizienter.



  • Ok stimmt wohl, aber wenn eine Datei ca. 10.000 Zeilen hat, belastet das nicht ganz schön das Programm? Ich mein die Zeilen befinden sich ja dann alle im Speicher.



  • glanfaenger schrieb:

    Ok stimmt wohl, aber wenn eine Datei ca. 10.000 Zeilen hat, belastet das nicht ganz schön das Programm? Ich mein die Zeilen befinden sich ja dann alle im Speicher.

    Äh... Ja und? Ein heutiger PC hat locker 4 GB Speicher, da fallen ~100 kB nicht so auf... 😃



  • Sone schrieb:

    Erstmal braucht er einen ifstream .

    Warum?



  • Swordfish schrieb:

    Sone schrieb:

    Erstmal braucht er einen ifstream .

    Warum?

    Nein, natürlich ist es kein muss.
    Es macht aber hier überhaupt keinen Sinn einen fstream zu nehmen, wo er nur lesen will.



  • warum?



  • warumdennnur schrieb:

    warum?

    Warum? Weil es schlechter Stil ist.
    Wenn man einen fstream nimmt suggeriert man, dass man durch diesen Stream lesen und schreiben möchte.
    Außerdem kann ein fstream ohne entsprechendes Flag die Datei auch ungewollt erzeugen.



  • Sone schrieb:

    Außerdem kann ein fstream ohne entsprechendes Flag die Datei auch ungewollt erzeugen.

    Wann genau legt denn der c-tor von fstream eine Datei an?



  • Swordfish schrieb:

    Sone schrieb:

    Außerdem kann ein fstream ohne entsprechendes Flag die Datei auch ungewollt erzeugen.

    Wann genau legt denn der c-tor von fstream eine Datei an?

    Wenn keine mit entsprechendem Namen vorhanden ist und du das out Flag (implizit oder explizit) mit angibst.



  • Oh man... das darf doch einfach nicht wahr sein...
    Natürlich darf das in Flag nicht angegeben sein 😃 sry

    Damit entfällt mein Argument Nr. 2. Aber 1 gilt noch.


Log in to reply