for_each ausgabe einer klasse



  • Gustl schrieb:

    Jetzt habe ich ein anderes Problem...
    Der Borland Builder bringt mir eine stack overflow fehlermeldung bei öfterem starten des programms.

    Ich zeige euch jetzt mal den kompletten code, bitte nicht lachen, etwas anfängerstyle hat er.

    main.cpp

    #include <iostream>
    #include "adressliste.h"
    using namespace std;
    
    int main()
    {   Adressliste mylist;
        //mylist.loadfromfile(); //dateinamen angeben!?
        mylist.eingabe(); //für sowas hast du doch extra operatoren überladen (>> und <<)
        mylist.eingabe(); //   ---- " -----
        mylist.ausgabe(); //   ---- " -----
        mylist.savetofile(); //dateinamen angeben?!
        system("PAUSE"); //schlechte variante die konsole offen zu lassen... siehe dazu auch Consolen-FAQ
        return 0; //unnötig
    }
    

    adresse.cpp

    #include <string> //solltest du im header schon haben
    #include <iostream> // ----- " ----
    #include <iomanip> //verwendest du nie
    #include "adresse.h"
    
    using namespace std;
    
    Adresse::Adresse(string n, string v, string t) //größere datentypen übergibt man in der Regel nicht per Value(Kopie) sondern per const Referenz (const string &n)
    //initialisierungsliste nutzen! :
     : name (n), vorname (v), telefonnr (t)
    {/*  name= n;
       vorname= v;
       telefonnr= t;
    ist damit unnötig*/
    }
    
    #if 0 //zum ausklammern des codes hab ich hier mal den Präprozessor genutzt - wollte es nicht ganz löschen
    ostream& operator<<(ostream& o, Adresse& T) //T ist zwar nicht gerade nen toller name dafür, aber das eigtl Problem ist, dass du hier eine Referenz nimmst und keine const Referenz - somit kann man kein const Objekt ausgeben
    #endif
    ostream& operator << (ostream &o, const Adresse &T)
    {   return o<<T.name<<" "<<T.vorname<<" "<<T.telefonnr<<endl;}
    
    istream& operator>>(istream& i, Adresse& T)
    {//üblicherweise sind Ein- und Ausgabe unabhängig von cout / cin zu implementieren! also:
        /*cout<<"Name: ";*/ i >> T.name; 
        /*cout<<"Vorname: ";*/ i>>T.vorname;
        /*cout<<"Telfonnummer: ";*/ i>>T.telefonnr;
        return i;
    }
    

    adresse.h

    #include <string>
    #include <iostream>
    //using namespace std;
    /*wurde glaube ich schon erwähnt, dass man das nicht tut...*/
    
    #ifndef ADRESSE_H_INCLUDED
    #define ADRESSE_H_INCLUDED
    //das hattest du vergessen, das #endif hattest du aber - hab mir die fehlermeldung zwar net durchgelesen, aber das wird sie gewesen sein ^^
    
    class Adresse
    {     protected: //ich würde private nehmen
          string name, vorname, telefonnr;
          public:
                 Adresse(const std::string &n="", const std::string &v="", const std::string &t=""); //übergaben per const referenz und namensraum mit angebgen
                 friend std::ostream& operator<<(std::ostream& o, const Adresse& T); //namensraum + ref als const gemarkt
                 friend std::istream& operator>>(std::istream& i, Adresse& T);
    /*Getter + Setter fehlen, z.Bsp.:*/
                 const std::string& GetName() const //die funktion ändert das objekt nicht, deshalb das const nach der Parameterliste (die in dem Fall leer ist)
                     { return name; }
                 void SetName(const std::string &_name)
                     { name = _name; }
    }; //namensraum
    #endif //#ifndef ADRESSE_H_INCLUDED
    

    adressliste.cpp

    #include "adressliste.h"
    #include <iostream>
    #include <algorithm>
    #include <fstream>
    using namespace std;
    
    fstream f; //schlechte angewohnheit, globale Variable zu nutzen - und eigtl auch immer vermeidbar
    
    #if 0 /* für so etwas gibt es operatoren >> und << - und dann machst du eben nur ne Funktion Add(const Adresse &value)*/
    void Adressliste::eingabe()
    {
       Adresse tmp;
       cin>>tmp;
       liste.push_back(tmp);
    }
    
    void console(Adresse& T)
    {
      cout<<T;
    }
    
    void Adressliste::ausgabe()
    {
      for_each(liste.begin(), liste.end(), console);
    }
    
    void elementspeichern(Adresse &tmp)
    {  f<<tmp;
       }
    
    void Adressliste::savetofile()
    {  f.open("datei.txt", ios::out);
       if(!f)cout<<"Fehler beim Oeffnen der Datei \"datei.txt\"!";
       else
       { for_each(liste.begin(), liste.end(), elementspeichern);
         f.close();
         }
       }
    
    void Adressliste::loadfromfile()
    {  Adresse tmp;
       f.open("datei.txt", ios::in);
       if(!f)cout<<"Fehler beim Oeffnen der Datei \"datei.txt\"!";
       else
       { f>>tmp;
         while(!f.eof())
         {  liste.push_back(tmp);
            f>>tmp;
            }
         f.close();
         }
    }
    #endif
    

    adressliste.h

    //---------------------------------------------------------------------------
    #ifndef adresslisteH
    #define adresslisteH
    //---------------------------------------------------------------------------
    #include "adresse.h"
    #include <list>
    
    class Adressliste:public Adresse //die vererbung ist hier nicht richtig - Adressliste ist keine Adresse sondern beinhaltet nur Adressen -> nur nen Container mit Adresse als template-Parameter als Member, hast du ja aber schon (std::list <Adresse> liste)
    {
          private: //ist es zwar per default, aber ich würds trotzdem mit hinschreiben
                 list<Adresse> liste;
          public:
                 void eingabe();
                 void ausgabe();
                 void savetofile();
                 void loadfromfile();
    };
    #endif
    

    Hoffe, du siehst noch bissl durch und nimmst dir die Zeit, das alles mal durchzulesen und deine Verbesserung hier zu posten - nat. darfst du auch fragen, falls du etwas (noch) nicht verstehst...

    bb



  • Ihr macht euch echt sehr viel mühe mir zu helfen, das finde ich einfach klasse und spreche hiermit ein großes lob aus. 🙂

    Aa ich heute Arbeiten muss und Abends in die Schule geh, werde ich nicht viel Zeit haben den code zu überarbeiten. Werde mich morgen drauf stürzen und poste meine abgewandelte version vom code hier ins Forum, aber die 2 Klassen würde ich schon gerne beibehalten, da dies genau in der Aufgabenstellung so drin steht.

    Ich habe mir eure posts genau durchgelsen und hab festgestellt das ich ganz sicher hier noch Verständnisprobleme haben werde:

    // 1. Datei Öffnen 
        std::fstream datei(dateiname.c_str(), std::ios::in); 
        if(datei.bad()) 
            return adressen; 
    
        // 2. Daten übertragen 
        std::copy( 
            std::istream_iterator<Adresse>(datei),  // Vom Dateibegin... 
            std::istream_iterator<Adresse>(),       // ...bis kein Eintrag mehr existiert 
            std::back_insert_iterator<std::list<Adresse> >(adressen)); // an die Liste hängen
    
    dateiname.c_str(),
    

    Keine ahnung was diese c_str() bringt...

    datei.bad())
    

    ebenso

    std::copy( 
            std::istream_iterator<Adresse>(datei),  // Vom Dateibegin... 
            std::istream_iterator<Adresse>(),       // ...bis kein Eintrag mehr existiert 
            std::back_insert_iterator<std::list<Adresse> >(adressen)); // an die Liste hängen
    

    das mus sich wohl einfach mal probieren, aber was der iterator da soll ist mir auch unverständlich, haben doch gar keinen bestimmt...?

    der rest ist mir verständlich, zumindest kann ich mir es denken.
    Danke euch 😃

    MfG Gustl



  • Gustl schrieb:

    ...aber die 2 Klassen würde ich schon gerne beibehalten, da dies genau in der Aufgabenstellung so drin steht.

    Dann gehe ich mal davon aus das du die Adressliste selbst (sprich ohne std::list oder vergleichbares) implementieren sollst.

    Gustl schrieb:

    Ich habe mir eure posts genau durchgelsen und hab festgestellt das ich ganz sicher hier noch Verständnisprobleme haben werde:

    // 1. Datei Öffnen 
        std::fstream datei(dateiname.c_str(), std::ios::in); 
        if(datei.bad()) 
            return adressen;
    
    dateiname.c_str(),
    

    Keine ahnung was diese c_str() bringt...

    datei.bad())
    

    ebenso

    std::fstream erwartet als ersten Parameter einen C-String, std::string gibt über die Funktion .c_str() eben einen solchen (konstanten) zurück. Und was die Funktion bad() von fstream angeht, sollte dein Englisch ausreichen um dies zu verstehen.

    Im nächsten C++ Standard wird fstream auch std::string als direkten Parameter zulassen.

    Gustl schrieb:

    std::copy( 
            std::istream_iterator<Adresse>(datei),  // Vom Dateibegin... 
            std::istream_iterator<Adresse>(),       // ...bis kein Eintrag mehr existiert 
            std::back_insert_iterator<std::list<Adresse> >(adressen)); // an die Liste hängen
    

    das mus sich wohl einfach mal probieren, aber was der iterator da soll ist mir auch unverständlich, haben doch gar keinen bestimmt...?

    Auch Datenströme haben Iteratoren. Das Konzept der Iteratoren zieht sich durch das gesamte C++, was auch Sinn macht um viele Ähnliche Abläufe zu vereinheitlichen.

    Und hier spielt dein "operator>>(istream&, Adresse&" eine wesentliche Hauptrolle. Der std::back_insert_iterator Iteriert über das Listenende mittels "push_back"...

    cu André



  • So Leute, jetzt bin ich schon sehr verwundert.

    Ich habe das ganze Projekt nochmal von neuem begonnen (bzw. wollte), mit Hilfe eurer Hifestellungen.
    Aber beim Versuche das Ding zu starten bringt er mir wieder den stack_overflow Fehler...

    Gut, ich habe jetzt euer std:: nicht befolgt, aber daran kann es doch wirklich nicht liegen oder?

    main.cpp

    #include <string>
    #include <iostream>
    #include "adresse.h"
    
    using namespace std;
    
    int main()
    {   Adresse Test("Rolf","Mueller","Hintere Pfaffenleite","8","08991-666");
        cout<<Test;
        //Test.loadfromfile();
        //Test.eingabe();
        //Test.eingabe();
        //Test.ausgabe();
        //Test.savetofile();
        getchar();
        return 0;
    }
    

    adresse.h

    //---------------------------------------------------------------------------
    #ifndef adresseH
    #define adresseH
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    class Adresse
    {   string name;
        string vorname;
        string street;
        string hausnr;
        string phone;
        public:
           Adresse(
              string const & name="",
              string const & vorname="",
              string const & street="",
              string const & hausnr="",
              string const & phone="")
    :         name(name),
              vorname(vorname),
              street(street),
              hausnr(hausnr),
              phone(phone)
              {}
    
           friend ostream& operator<<(ostream& outstream, Adresse & const adresse);
    };
    //---------------------------------------------------------------------------
    #endif
    

    adresse.cpp

    //---------------------------------------------------------------------------
    #include "adresse.h"
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    ostream& operator<<(ostream& outstream, Adresse & const adresse)
    {   outstream << adresse.name << " "
                  << adresse.vorname << " "
                  << adresse.street << " "
                  << adresse.hausnr << " "
                  << adresse.phone;
        return outstream;
    }
    
    //---------------------------------------------------------------------------
    

    Das ist der komplette code...

    Bei der .h bringt er mir bei

    string const & name="",
    

    ein Warning:
    "Cannot create pre-compieled header: initialized data in header"

    Benutze Borland Enterprise Suite Version 6.0 von 2002

    Woran kanns denn liegen?
    MfG Gustl

    EDIT: Habe es jetzt auf einen anderen Rechner versucht zu starten, dort konnte ich es ohne Probleme 3-4x aufrufen, dann war wieder schluß(stack overflow) und ich musste den borland wieder über den taskmanager beenden.



  • Hmm. Das Ding ist recht alt. Hast du es schon mal mit etwas aktuellerem versucht? (VC, oder GCC z.B)

    Ansonsten sehe ich vom Code her abgesehen von den falsch verwendeten consts nichts.

    Die Fehlermeldung sagt dir wahrscheinlich ja, was das Problem bei dir ist. Nimm die Defaultinitialisierung mal raus. Dann sollte es auch funktionieren.

    Am std:: liegts sicher nicht. (Es sei denn du hättest ein sehr merkwürdiges und irgendwie reinpassendes Konstrukt, dass dir einen Laufzeitfehler verursacht was bei dir nicht der Fall ist).



  • Habe es jetzt mit visual studio 2005 probiert, und siehe da, kein stack overflow mehr. 🙂



  • Wenn du in Zukunft Funktionen oder Klassen aus der Standardbibliothek nicht kennst, kannst du sie in einer C++-Referenz deiner Wahl nachschlagen. Ich empfehle www.cplusplus.com.



  • ok, danke.

    Aber eine weiter Sache die ich nicht verstehe ist folgendes,

    ich habe zwei Klassen (adresse.h & adressliste.h)
    in der adressliste habe ich #include "adresse.h" damit ich bei den Eigenschaften list<Adresse> Liste; sagen kann.
    In der cpp von adressliste kann ich ja dann ohne include "adresse.h" ein objekt von adresse erzeugen.. ist das normal?



  • Ja, da du den Header "adresse.h" indirekt über "adressliste.h" auch inkludierst, ist die Klasse dort bekannt.



  • Gustl schrieb:

    Gut, ich habe jetzt euer std:: nicht befolgt, aber daran kann es doch wirklich nicht liegen oder?

    Nein, aber ich rate dir wirklich dringen vom using namespace in Headern (sowie vor includes) ab. Wenn du einmal mehrere Bibliotheken verwendest oder ein großes Projekt hast, ist der Aufwand dies nachträglich bei Namenskonflikten (Die immer realistischer werden um so mehr Bibliotheken oder allgemein Code vorliegt) zu korrigieren meist höher als der Aufwand wenn man es gleich macht.

    using namespace sollte man so lokal wie möglich verwenden, in einen Header wird es aber sehr leicht zu einer globalen Einstellung über das Gesamtprojekt.

    Es spricht wenig dagegen es in Sourcedateien (Dann muss man nur die Dateien anpassen wo tatsächlich Mehrdeutigkeiten auftreten), oder in Funktionsrümpfen zu verwenden.



  • neues problem mit sort...hmpf

    folgender code:

    void Adressliste::sortieren()
    {	std::sort(liste.begin(), liste.end(), sortname);
    }
    

    sortname ist in der adresse.h mit friend deklariert.

    friend bool sortname(const Adresse &a, const Adresse &b);
    

    methode dazu in der adresse.cpp:

    bool sortname(const Adresse &a, const Adresse &b)
    {	if(a.hausnr < b.hausnr)return true;
    	else return false;
    

    Fehlermeldungen:
    Fehler 7 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903

    Fehler 8 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903

    Fehler 9 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903

    Fehler 10 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903

    Fehler 11 error C2676: Binärer Operator '-': 'std::list<_Ty>::_Iterator<_Secure_validation>' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht c:\program files\microsoft visual studio 8\vc\include\algorithm 2903
    Fehler 12 error C2780: 'void std::_Sort(_RanIt,_RanIt,_Diff)': Erwartet 3 Argumente - 4 unterstützt c:\program files\microsoft visual studio 8\vc\include\algorithm 2903

    Versteh ich nicht, dies ging z.B. wieder mit den borland... hmpf
    ich übergebe doch 3 parameter...

    Habe auch schon probiert den operator < zu überlagern... und somit dann nur

    std::sort(liste.begin(), liste.end());
    

    angeben, habe gelesen das man mit den < operator nur an sort zwei parameter übergeben muss, quasi anfang und ende... geht aber auch nicht...

    @asc
    Ja, ich sollte es mir gewiss angewöhnen, aber wenn das unser Lehrer nicht macht, gewöhne ich es mir vorerst nicht an.
    Da wir die Prüfungen per hand schreiben und er das auch komischerweise nicht will^^

    MfG Gustl



  • Du kannst std::sort() nicht auf eine std::list anwenden, da diese keine Random-Access-Iteratoren unterstützt. Benutze dazu die Memberfunktion std::list::sort() .



  • ahhh, da liegt der hund begraben.. stimmt mit einem programm vauf borland habe ich auch deque verwendet. danke



  • Noch eine kleine Verständnisfrage zu const:

    heißt es nun so

    friend ostream& operator<<(ostream& outstream, const Adresse & adresse);
    

    oder doch so

    friend ostream& operator<<(ostream& outstream, Adresse const & adresse);
    

    ?


  • Administrator

    Ist das gleiche. Was dir lieber ist.

    Grüssli



  • Also langsam vergeht mir der Spaß...

    Jetzt bringt der Compiler von Visual Studio auch einen Überlauf Fehler...

    Hier der Code:

    //main.cpp-------------------------------------------------------------------------
    #include <string>
    #include <iostream>
    #include <list>
    #include "adressliste.h"
    
    const char dateiname[]="datei.txt";
    
    int main()
    {   Adressliste Freunde;
    //--einfuegen---------------------------------------------------------------------
    	Adresse Address1("Denny","Fischer","fuckweg","8","08484-234");
    	Adresse Address2("Heid","Stefan","langweg","23","08484-297");
    	Adresse Address3("Schoeninger","Sebastian","kurzweg","4","0848-1984");
    	std::cout<<"3 Adressen in Objekt einfuegen..."<<std::endl;
    	Freunde.einfuegen(Address1);
    	Freunde.einfuegen(Address2);
    	Freunde.einfuegen(Address3);
    //--speichern---------------------------------------------------------------------
    	std::cout<<std::endl<<"speichern..."<<std::endl;
    	Freunde.savetofile(dateiname);
    //--ausgeben----------------------------------------------------------------------
    	std::cout<<std::endl<<"ausgeben auf console..."<<std::endl;
    	Freunde.ausgabe();
    //--sortieren---------------------------------------------------------------------
        std::cout<<std::endl<<"sortieren..."<<std::endl;
    	Freunde.sortieren();
    //--ausgeben----------------------------------------------------------------------
    	std::cout<<std::endl<<"ausgeben auf console (sortiert)..."<<std::endl;
    	Freunde.ausgabe();
    //--loeschen----------------------------------------------------------------------
    	std::cout<<std::endl<<"loeschen...dann leere liste ausgeben..."<<std::endl;
    	Freunde.loeschen();
    	Freunde.ausgabe();
    //--laden-------------------------------------------------------------------------
        std::cout<<std::endl<<"laden von file..."<<std::endl;
    	Freunde.loadfromfile(dateiname);
    //--ausgeben----------------------------------------------------------------------
    	std::cout<<std::endl<<"geladene lsite ausgeben..."<<std::endl;
    	Freunde.ausgabe();
    
        getchar();
        return 0;
    }
    //--------------------------------------------------------------------------------
    
    //adresse.h-------------------------------------------------------------------
    #ifndef adresseH
    #define adresseH
    #include <string>
    #include <iostream>
    
    class Adresse
    {   std::string name;
        std::string vorname;
        std::string street;
        std::string hausnr;
        std::string phone;
        public:
           Adresse(
              std::string name="",
              std::string vorname="",
              std::string street="",
              std::string hausnr="",
              std::string phone="")
    :         name(name),
              vorname(vorname),
              street(street),
              hausnr(hausnr),
              phone(phone)
              {}
    
           friend std::ostream& operator<<(std::ostream& outstream, Adresse const & adresse);
           friend std::istream& operator>>(std::istream& instream, Adresse const & adresse);
    	   friend bool sortname(const Adresse &a, const Adresse &b);
    };
    //---------------------------------------------------------------------------
    #endif
    
    //adresse.cpp----------------------------------------------------------------
    #include "adresse.h"
    #include <string>
    #include <iostream>
    
    std::ostream& operator<<(std::ostream& outstream, Adresse const & adresse)
    {   outstream << adresse.name << " "
                  << adresse.vorname << " "
                  << adresse.street << " "
                  << adresse.hausnr << " "
                  << adresse.phone << std::endl;
        return outstream;
    }
    
    std::istream& operator>>(std::istream& instream, Adresse const & adresse)
    {   instream >> adresse.name;
        instream >> adresse.vorname;
        instream >> adresse.street;
        instream >> adresse.hausnr;
        instream >> adresse.phone;
        return instream;
    }
    
    bool sortname(const Adresse &a, const Adresse &b)
    {	if(a.name < b.name)return true;
    	else return false;	
    }
    //---------------------------------------------------------------------------
    
    //adressliste.h---------------------------------------------------------------
    #ifndef adresslisteH
    #define adresslisteH
    #include <deque>
    #include "adresse.h"
    
    class Adressliste
    {	std::deque<Adresse> liste;
    	std::deque<Adresse>::iterator it;
            public:
    		void einfuegen(Adresse const & address);
    
    		void savetofile(char const *dateiname);
    		void loadfromfile(char const *dateiname);
    
    		void sortieren();
    		void ausgabe();
    		void loeschen();
    };
    //---------------------------------------------------------------------------
    #endif
    
    //adressliste.cpp-----------------------------------------------------------------
    #include "adressliste.h"
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <deque>
    #include <algorithm>
    
    void Adressliste::einfuegen(Adresse const & address)
    {	liste.push_back(address);
    }
    
    void Adressliste::savetofile(char const *dateiname)
    {	std::fstream f;
    	f.open(dateiname, std::ios::out);
    	if(!f)std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl;
    	else 
    	{	for(it= liste.begin(); it != liste.end(); ++it)
    	    f<<*it;
    		std::cout<<"--- Liste in "<<dateiname<<" gespeichert! ---"<<std::endl;
    	}
    	f.close();
    }
    
    void Adressliste::loadfromfile(char const *dateiname)
    {	std::fstream f;
    	Adresse tmp;
    	f.open(dateiname, std::ios::in);
    	if(!f)std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl;
        else
        {	f>>tmp;
            while(!f.eof())
            {	liste.push_back(tmp);
                f>>tmp;
            }
    		std::cout<<"--- Liste aus "<<dateiname<<" geladen! ---"<<std::endl;
    		f.close();
        }
    }
    
    void Adressliste::sortieren()
    {	std::sort(liste.begin(), liste.end(), sortname);
    }
    
    void Adressliste::ausgabe()
    {	for(it= liste.begin(); it != liste.end(); ++it)
    	std::cout<<*it;	
    }
    
    void Adressliste::loeschen()
    {	liste.clear();
    }
    

    sobald er also von der file laden will hat er überlauf...

    das programm läuft bis zum Freunde.loadfromfile(dateiname); da ist dann schluss und es kommt die fehlermeldung:
    Fehlermeldung von Visual:
    "Unbehandelte Ausnahme bei 0x004143e7 in adresse.exe: 0xC00000FD: Stack overflow."

    Mach echt keinen Spaß mehr...



  • Wann kracht es denn überhaupt? Direkt beim starten, beim schreiben, beim lesen? Bist Du mal mit dem Debugger durchgesteppt?

    Ansonsten noch zwei Kleinigkeiten:

    Für

    if(a.name < b.name)return true;
        else return false;
    

    gibt es die geheime Kurzschreibweise

    return a.name < b.name;
    

    Du brauchst außerdem Deine streams nicht selber schließen, das mach der Destruktor für Dich. Zum einlesen würde ich einen ifstream nehmen, zum rausschreiben einen ofstream. Außerdem ist der Vergleich mit eof möglicherweise nicht ganz das was Du willst. Ich würde die Einleseroutine etwa wie folgt schreiben:

    void Adressliste::loadfromfile(char const *dateiname)
    {    
        std::ifstream f(dateiname);
        if(!f) {
            std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl;
            return;
        }
    
        for(Adresse tmp;f>>tmp;)
            liste.push_back(tmp);
    
        std::cout<<"--- Liste aus "<<dateiname<<" geladen! ---"<<std::endl;
    }
    


  • Jester schrieb:

    Wann kracht es denn überhaupt? Direkt beim starten, beim schreiben, beim lesen? Bist Du mal mit dem Debugger durchgesteppt?

    Der Überlauf muss mit der Methode loadfromfil geschehen.. wenn ich es ausklammer funktioniert das programm. Aber auch mit deiner Version gehts leider nicht und es kommt zum überlauf...

    Jester schrieb:

    Für

    if(a.name < b.name)return true;
        else return false;
    

    gibt es die geheime Kurzschreibweise

    return a.name < b.name;
    

    Richtig, habe ich auch schon gesehen, aber bin nicht drauf gekommen...
    Danke.

    Jester schrieb:

    Du brauchst außerdem Deine streams nicht selber schließen, das mach der Destruktor für Dich.

    Wo genau schließe ich die selbst?

    Jester schrieb:

    Zum einlesen würde ich einen ifstream nehmen, zum rausschreiben einen ofstream. Außerdem ist der Vergleich mit eof möglicherweise nicht ganz das was Du willst. Ich würde die Einleseroutine etwa wie folgt schreiben:

    void Adressliste::loadfromfile(char const *dateiname)
    {    
        std::ifstream f(dateiname);
        if(!f) {
            std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl;
            return;
        }
    
        for(Adresse tmp;f>>tmp;)
            liste.push_back(tmp);
    
        std::cout<<"--- Liste aus "<<dateiname<<" geladen! ---"<<std::endl;
    }
    

    Wie gesagt, wenn ich meinen mit deinem code ersetze habe ich das gleiche Problem. 😞

    Edit:
    nach der Fehlermeldung öffnet mir visual die datei xstring
    und bringt mir einen pfeil auf

    size_type __CLR_OR_THIS_CALL max_size() const
    		{	// return maximum possible length of sequence
    		size_type _Num = _Mybase::_Alval.max_size();
    		return (_Num <= 1 ? 1 : _Num - 1);
    		}
    

    zudem ist mir auch nicht ganz klar was hier genau passiert:

    for(Adresse tmp;f>>tmp;)
            liste.push_back(tmp);
    

    Könnte mir das vielleicht wer kurz erklären?



  • Wo sind denn die Fachmänner die mir sagen können warum ich bei loadfromfile(..) ein stack overflow bekomme/verursache?

    Wäre echt klasse wenn mir hier einer licht ins dunkle bringt.



  • Gustl schrieb:

    Wo sind denn die Fachmänner die mir sagen können warum ich bei loadfromfile(..) ein stack overflow bekomme/verursache?

    Ich habe dir schon vor zwei Seiten gesagt, du solltest einen Debugger benutzen. Solche Dinge sind eigentlich deine Aufgabe. Wenn wir nicht gerade etwas im Code sehen, können wir dir auch nicht helfen. Prüf doch die Variablen auf ihre Gültigkeit. Wenn du im Debug-Mode ausführst, sollte dir die STL bei Fehlern passende Assertions liefern.

    for(Adresse tmp;f>>tmp;)
            liste.push_back(tmp);
    

    Das funktioniert wie jede For-Schleife. Zu Beginn wird ein Adresse -Objekt namens tmp erstellt. Während der Ausdruck f>>tmp wahr ist (solange eingelesen wird und der Stream sich in einem korrekten Zustand befindet), wird an die Liste angehängt. Hier würde ich allerdings eher eine While-Schleife nehmen. Wird die Schleife durchlaufen? Endet sie?


Anmelden zum Antworten