ifstream liest zu viel aus ?



  • Hallo

    Ich schreibe gerade ein Adressbuch.

    Ich habe in meinen Konstruktor eingebaut dass er beim initialisieren die Daten
    aus der txt Datei ausliest und sie in ein vector speichert.

    Address::Address()
    {
    	char buffer[bufferSize];
    	std::ifstream iaddresstxt;
    	iaddresstxt.open("address.txt");
    
    	if(!iaddresstxt)
    	{
    		std::ofstream oaddresstxt;
    		oaddresstxt.open("address.txt");
    		oaddresstxt.close();
    	}
    
    	else
    	{
    		do
    		{
    			iaddresstxt.getline(buffer, bufferSize);	firstName.push_back(buffer);	buffer[0] = '\0';
    			iaddresstxt.getline(buffer, bufferSize);	lastName.push_back(buffer);		buffer[0] = '\0';
    			iaddresstxt.getline(buffer, bufferSize);	dateOfBirth.push_back(buffer);	buffer[0] = '\0';
    			iaddresstxt.getline(buffer, bufferSize);	phoneNumber.push_back(buffer);	buffer[0] = '\0';
    			iaddresstxt.getline(buffer, bufferSize);	address.push_back(buffer);		buffer[0] = '\0';
    			iaddresstxt.getline(buffer, bufferSize);	location.push_back(buffer);		buffer[0] = '\0';
    		}while(!iaddresstxt.eof());
    	}
    	iaddresstxt.close();
    }
    

    wen ich dass Programm dann neu starte hat er meine Daten und ein zweiten mit leeren strings 😞

    was mach ich falsch ?



  • der ist am ende der letztem readline() noch nicht im eof state, das passiert erst wenn er einmal drübergelesen hat, da ist er dann schon am Anfan deiner do {\ while () und daher haste 2 Datensätze.



  • Als Tipp könntest du in deinem Programm RAII verwenden.

    std::ifstream iaddresstxt;
    iaddresstxt.open("address.txt");
    

    wird zu

    std::ifstream iaddresstxt("address.txt");
    

    Dito für das ofstream. Und .close() musst du nicht aufrufen, da die filestreams beim Scopeende automatisch geschlossen werden.



  • Sorry, Offtopic.
    Aber mach doch eine Funktion namens Load die einen std::string als Parameter verlangt. Mach, meiner Meinung nach, mehr Sinn als im Ctor.

    MfG, EOutOfResources



  • Und wie mache ich dass jetzt das er danach in den eof status kommt ?



  • Vorsicht bei Leerzeichen musst du es anders machen 😉

    Edit: Um Savefunktion erweitert.

    Quellcode:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    class Person
    {
    private:
    	std::string name;
    	std::string vorname;
    	std::string geburtstag;
    	std::string telefonnummer;
    	std::string adresse;
    	std::string ort;
    
    public:
    	friend std::ostream& operator << (std::ostream& out, const Person& pers);
    	friend std::istream& operator >> (std::istream& in, Person& pers);
    };
    
    std::ostream& operator << (std::ostream& out, const Person& pers)
    {
    	out << pers.name << "\n"
    		<< pers.vorname << "\n"
    		<< pers.geburtstag << "\n"
    		<< pers.telefonnummer << "\n"
    		<< pers.adresse << "\n"
    		<< pers.ort << "\n";
    	return out;
    }
    
    std::istream& operator >> (std::istream& in, Person &pers)
    {
    	in  >> pers.name
    		>> pers.vorname
    		>> pers.geburtstag
    		>> pers.telefonnummer
    		>> pers.adresse
    		>> pers.ort;
    
    	return in;
    }
    
    class Adressen
    {
    private:
    	std::vector<Person> vecAdressen;
    
    public:
    	bool Load(std::string datei);
    	bool Save(std::string datei);
    	friend std::ostream& operator << (std::ostream& out, const Adressen& adr);
    };
    
    bool Adressen::Load(std::string datei)
    {
    	std::ifstream in(datei);
    	if(!in) return false;
    
    	while (!in.eof())
    	{
    		Person pers;
    		in >> pers;
    
    		vecAdressen.push_back(pers);
    	}
    
    	return true;
    }
    
    bool Adressen::Save(std::string datei)
    {
    	std::ofstream out(datei);
    	if(!out) return false;
    
    	for(std::vector<Person>::const_iterator i = vecAdressen.begin(); i != vecAdressen.end(); ++i)
    		out << *i;
    
    	return true;
    }
    
    std::ostream& operator << (std::ostream& out, const Adressen& adr)
    {
    	for(std::vector<Person>::const_iterator i = adr.vecAdressen.begin(); i != adr.vecAdressen.end(); ++i)
    		out << *i << "\n";
    	return out;
    }
    
    int main()
    {
    	Adressen adr;
    	if(adr.Load("test.txt"))
    		std::cout << adr;
    
    	adr.Save("test_save.txt");
    }
    

    Testdatei:

    Mustermann
    Max
    12.07.2010
    0123/456789
    Hauptstr.777
    Berlin
    Musterfrau
    Maria
    20.12.2008
    0110/456789
    Hauptstr.2
    Muenchen
    


  • Vielen Dank an alle 🙂


Anmelden zum Antworten