[GELÖST] Problem mit Daten ausgeben aus Vektor



  • Hey Leute, ich habe ein Problem und kann einfach den Fehler nicht finden=(
    Und zwar habe ich eine Datei in der Adressen stehen, ich möchte die Daten auslesen, im Vektor speichern, sortieren und anschließend sortiert ausgeben.
    Hier mal der Code:

    void sortiertAusgeben()
    {
        ifstream fin( "Adressen.txt", ios::in );
        if ( !fin )
            cout << "Datei konnte nich zum lesen geöffnet werden!\n";
        else
        {
            int i = 0;
            char temp;
            string vorname;
            string nachname;
            string adresse;
            string tele;
            string email;
            while (fin.get( temp ) )
            {
                if( temp == '_' ) // Zählen wie viele Adresse vorhanden sind
                    ++i;
            }
            fin.close();
    
            vector<Adresse> Adressen( i );
    
            fin.open( "Adressen.txt", ios::in );
    
            for( int j = 0; j < i; ++j )
            {
                getline( fin, vorname );
                getline( fin, nachname );
                getline( fin, adresse );
                getline( fin, tele );
                getline( fin, email );
                Adressen[j] = Adresse( vorname, nachname, adresse, tele, email );
                while( fin.get( temp ) )
                {
                    if( temp == '_' ) // Da bei '_' eine Neue Adresse losgeht
                        break;
                }
            }
            fin.close();
    
            sort( Adressen.begin(), Adressen.end(), &sortiereNachVornamen );
            for( int j = 0; j < i; ++j )
            {
                cout << Adressen[j].getVorname() << "\n";
                cout << Adressen[j].getNachname() << "\n";
                cout << Adressen[j].getAdresse() << "\n";
                cout << Adressen[j].getTele() << "\n";
                cout << Adressen[j].getEmail() << "\n\n\n";
            }
        }
    }
    
    bool sortiereNachVornamen(const Adresse& lhs, const Adresse& rhs)
    {
        return lhs.getVorname() < rhs.getVorname();
    }
    

    Hoffe ihr könnt mir helfen, denn das Programm funktioniert zwar, er gibt mir jedoch einfach nur leere Zeilen aus=(
    Danke schonmal für Eure Hilfe und Bemühungen;-)



  • Der Debugger ist dein Freund...

    1. Nutze std::ifstream::exception.
    2. Datei nur einmal öffnen.
    3. Zum zurückspringen std::ifstream::seekg() verwenden.
    4. Nicht mit ASCII-zeichen hantieren wenn es sich um Zahlen handelt.
    5. Wenn du die Werte per []-Operator zuweist, solltest du ebenfalls Exceptions verwenden, da der Speicher nicht angefordert wird, wenn das Limit überschritten wurde.
    6. Speicher dynamisch allokieren und std::vector::push_back() verwenden.
    7. "return lhs.getVorname() < rhs.getVorname();" wtf?


  • Mod

    Ich weiß nicht so recht, Kóyaánasqatsi, einige deiner Tipps passen hier nicht ganz:

    - Der Debugger ist dein Freund...
    👍 Ich kann den Fehler spontan auch nicht finden.

    1. Nutze std::ifstream::exception.
    👎 Wozu so umständlich? !fin ist doch in Ordnung und anfängerfreundlich

    2. Datei nur einmal öffnen.
    👍

    3. Zum zurückspringen std::ifstream::seekg() verwenden.
    👍 Oder sich das zurückspringen ganz sparen, mit Tipp 6.

    4. Nicht mit ASCII-zeichen hantieren wenn es sich um Zahlen handelt.
    👎 Wovon redest du? Doch wohl hoffentlich nicht von der Telefonnummer?

    5. Wenn du die Werte per []-Operator zuweist, solltest du ebenfalls Exceptions verwenden, da der Speicher nicht angefordert wird, wenn das Limit überschritten wurde.
    👍 Generell ja, wird hier aber wahrscheinlich nicht der Fehler sein.

    6. Speicher dynamisch allokieren und std::vector::push_back() verwenden.
    👍 Genau. Der Threadersteller macht das ganze sehr umständlich. Da ist ja der ganze Vorteil von vector dahin.

    7. "return lhs.getVorname() < rhs.getVorname();" wtf?
    👎 Was gibts daran auszusetzen?



  • Hey erst mal Danke=)
    Also genau sowas wie ifstream::seekg hab ich auch gesucht, blos irgendwie nicht gefunden, und dachte dann, mache ich es eben mit öffnen und schließen.
    Nun die Frage, wie genau nutze ich seekg, raff das net so ganz, was muss ich als parameter übergeben um an den Dateianfang zu springen?

    Hatte es auch erst mit push_back, da es nicht ging dachte ich vll gehts mit [], war dem wohl aber nicht so;-)

    Also wär cool wenn ihr mir das mit seekg kurz erklären könntet, vll geht es ja dann=)

    EDIT:
    Also wie seekg funktioniert hab ich jetzt rausgefunden, und auch eingebaut, hab auch jetzt wieder push_back reingemacht, es funktioniert jedoch trotzdem nicht=(


  • Mod

    Zeig mal eine minimale compilierbare Version (am liebsten die mit push_back, dann brauchst du auch kein seekg) und einen kurzen Abschnitt aus der Adressdatei mit dem sich das Problem reproduzieren lässt.



  • SeppJ schrieb:

    Ich weiß nicht so recht, Kóyaánasqatsi, einige deiner Tipps passen hier nicht ganz:

    1. Nutze std::ifstream::exception.
    👎 Wozu so umständlich? !fin ist doch in Ordnung und anfängerfreundlich

    Was hat !-Operator mit std::ifstream::exceptions zu tun? Es gibt noch weitere Flags.

    SeppJ schrieb:

    4. Nicht mit ASCII-zeichen hantieren wenn es sich um Zahlen handelt.
    Wovon redest du? Doch wohl hoffentlich nicht von der Telefonnummer?

    Sorry habe mich verguckt, habe nur schnell drüber geschaut und habe temp == '_' irgendwie im while()-Kopf gesehen.

    SeppJ schrieb:

    7. "return lhs.getVorname() < rhs.getVorname();" wtf?
    Was gibts daran auszusetzen?

    Ja. Warum sollte man überprüfen ob Vorname1 < Vorname2?

    @fr33g
    Keine Ahnung was du da startest, aber generell sollte fin.seekg(0); gehen



  • Ja ich überprüfe es um die Adressen nach Vorname sortiert auszugeben;-)

    mhh also hier mal bissel code der euch vll hilft;-)
    teil von funktionen.cpp

    #include "classAdresse.h"
    #include "funktionen.h"
    #include <iostream>
    #include <string>
    #include <map>
    #include <fstream>
    #include <vector>
    
    using namespace std;
    
    void menu( int& auswahl )
    {
        cout << "Was wollen sie tun:\n"; // Programmmenü
        cout << "Neue Adresse anlegen(1)\n";
        cout << "Adresse suchen(2)\n";
        cout << "Alle Adressen ausgeben(3)\n";
        cout << "Alle Adressen sortiert ausgeben(4)\n";
        cout << "Programm beenden(5)\n";
        cin >> auswahl;
    
        if( ( auswahl < 1 ) || ( auswahl > 5 ) )
        {
            cout << "Falsche Eingabe!\n";
            menu(auswahl);
        }
    }
    void adresseAnlegen( map<string, Adresse>& Adressen )
    {
        cout << "Geben sie den Vornamen ein: ";
        string vorname;
        cin >> vorname;
        cout << "Geben sie den Nachnamen ein: ";
        string nachname;
        cin >> nachname;
        cout << "Geben sie die Adresse ein: ";
        string adresse;
        cin.ignore();
        getline( cin, adresse );
        cout << "Geben sie die Telefonnummer ein: ";
        string tele;
        cin >> tele;
        cout << "Geben sie die Email-Adresse ein: ";
        string email;
        cin>> email;
    
        Adressen[vorname] = Adresse(vorname, nachname, adresse, tele, email); // Adresse wird erstellt in der map
    
        ofstream fout( "Adressen.txt", ios::app );
    
        if( !fout )
            cout << "Die Datei konnte nicht zum Schreiben geöffnet werden!\n";
        else
        {
            fout << "_" << Adressen[vorname].getVorname() << "\n"; // Eigenschaften in die Datei schreiben
            fout << Adressen[vorname].getNachname() << "\n";
            fout << Adressen[vorname].getAdresse() << "\n";
            fout << Adressen[vorname].getTele() << "\n";
            fout << Adressen[vorname].getEmail() << "\n\n\n";
        }
        fout.close();
    }
    void menuAuslesen( map<string, Adresse>& Adressen )
    {
        int auswahl;
    
        cout << "Wollen sie nach Vorname suchen(1)\n";
        cout << "Wollenn sie nach Nachname suchen(2)\n";
        cin >> auswahl;
        if ( ( auswahl < 1 ) || ( auswahl > 2 ) )
        {
            cout << "Falsche Eingabe!\n";
            menuAuslesen( Adressen );
        }
    
        switch( auswahl )
        {
            case 1:
            {
                auslesenVorname( Adressen ); // Öffnen der Funktion zum Auslesen bzw Suche per Vorname
                break;
            }
            case 2:
            {
                auslesenNachname( Adressen ); // Öffnen der Funktion zum Auslesen bzw Suche per Nachname
                break;
            }
        }
    }
    void sortiertAusgeben()
    {
        ifstream fin( "Adressen.txt", ios::in );
        if ( !fin )
            cout << "Datei konnte nich zum lesen geöffnet werden!\n";
        else
        {
            int i = 0;
            char temp;
            string vorname;
            string nachname;
            string adresse;
            string tele;
            string email;
            while (fin.get( temp ) )
            {
                if( temp == '_' ) // Zählen wie viele Adresse vorhanden sind
                    ++i;
            }
            vector<Adresse> Adressen;
    
            fin.seekg( 0, ios::beg );
    
            for( int j = 0; j < i; ++j )
            {
                getline( fin, vorname );
                getline( fin, nachname );
                getline( fin, adresse );
                getline( fin, tele );
                getline( fin, email );
                Adressen.push_back( Adresse( vorname, nachname, adresse, tele, email ) );
                while( fin.get( temp ) )
                {
                    if( temp == '_' ) // Da bei '_' eine Neue Adresse losgeht
                        break;
                }
            }
            fin.close();
    
            sort( Adressen.begin(), Adressen.end(), &sortiereNachVornamen );
            for( int j = 0; j < i; ++j )
            {
                cout << Adressen[j].getVorname() << "\n";
                cout << Adressen[j].getNachname() << "\n";
                cout << Adressen[j].getAdresse() << "\n";
                cout << Adressen[j].getTele() << "\n";
                cout << Adressen[j].getEmail() << "\n\n\n";
            }
        }
    }
    
    bool sortiereNachVornamen(const Adresse& lhs, const Adresse& rhs)
    {
        return lhs.getVorname() < rhs.getVorname();
    }
    

    class Adresse.h

    #ifndef CLASSADRESSE_H_INCLUDED
    #define CLASSADRESSE_H_INCLUDED
    
    #include <string>
    
    class Adresse
    {
        public:
            Adresse(){}
            Adresse(std::string vorname, std::string nachname, std::string adresse, std::string tele, std::string email);
            ~Adresse(){}
            std::string getVorname() const { return itsVorname; }
            void setVorname( std::string vorname );
            std::string getNachname() const { return itsNachname; }
            void setNachname( std::string nachname );
            std::string getAdresse() const { return itsAdresse; }
            void setAdresse( std::string adresse );
            std::string getTele() const { return itsTele; }
            void setTele( std::string tele );
            std::string getEmail() const { return itsEmail; }
            void setEmail( std::string email );
    
        private:
            std::string itsVorname;
            std::string itsNachname;
            std::string itsAdresse;
            std::string itsTele;
            std::string itsEmail;
    };
    #endif // CLASSADRESSE_H_INCLUDED
    

    und die main

    #include <iostream>
    #include <string>
    #include <map>
    #include <fstream>
    #include "classAdresse.h"
    #include "funktionen.h"
    
    using namespace std;
    
    int main()
    {
        bool stop = false;
        int auswahl;
        map<string, Adresse> Adressen;
    
        while( !stop )
        {
            menu(auswahl);
    
            switch( auswahl )
            {
                case 1:
                {
                    adresseAnlegen( Adressen );
                    break;
                }
                case 2:
                {
                    menuAuslesen( Adressen );
                    break;
                }
                case 3:
                {
                    alleAusgeben( Adressen );
                    break;
                }
                case 4:
                {
                    sortiertAusgeben();
                    break;
                }
                case 5:
                {
                    cout << "Programm wird beeendet!";
                    stop = true;
                    break;
                }
            }
        }
    }
    

    Hoffe mal des geht von der Codemenge und ihr könnt mir damit helfen=)



  • Mhh kann mir keiner weiter helfen=(?



  • Wenn du dir einfach interessante Werte an verschiedenen Stellen ausgeben lässt, hast du bei solchen Problemen den Fehler in einer Minute gefunden.
    Also z.B. vorname, nachname, usw. einmal nach dem Einlesen und dann im vector nach dem push (back() gibt dir das letzte Element).
    Außerdem wäre Adresse.cpp noch ganz interessant, wegen der Implementation des Konstruktors.
    Übrigens: strings immer per Referenz (const std::string&) übergeben, sonst werden davon überflüssigerweise Kopien angelegt und das ist bei Strings nicht ganz billig.



  • Ja dachte zu viel Code wär auch bissel blöd, dass ihr sonst zu viel zum lesen habt;-)
    Aber wäre wohl nötig gewesen.

    Aaaber ich habs jetzt grade eben selber hinbekommen, hab mir nochmal angeschaut wie ichs eigentlich bei den anderen Ausgabeoptionen gelöst hab und habs jetzt daher dass sortierte ausgeben nochmal bisschen grundlegend geändert, und siehe da es geht=)

    Poste trotzdem mal den Code.

    void sortiertAusgeben()
    {
        vector<Adresse> Adressen;
        ifstream fin( "Adressen.txt", ios::in );
        if ( !fin )
            cout << "Datei konnte nich zum lesen geöffnet werden!\n";
        else
        {
            char temp;
            string vorname;
            string nachname;
            string adresse;
            string tele;
            string email;
            while (fin.get( temp ) )
            {
                if( temp == '_' ) // Zählen wie viele Adresse vorhanden sind
                {
                    getline( fin, vorname );
                    getline( fin, nachname );
                    getline( fin, adresse );
                    getline( fin, tele );
                    getline( fin, email );
                    Adressen.push_back( Adresse( vorname, nachname, adresse, tele, email ) );
                }
            }
            fin.close();
    
            sort( Adressen.begin(), Adressen.end(), &sortiereNachVornamen );
    
            cout << endl;
    
            for( int j = 0; j < Adressen.size(); ++j )
            {
                cout << Adressen[j].getVorname() << "\n";
                cout << Adressen[j].getNachname() << "\n";
                cout << Adressen[j].getAdresse() << "\n";
                cout << Adressen[j].getTele() << "\n";
                cout << Adressen[j].getEmail() << "\n\n\n";
            }
    
        }
    }
    

    Also Danke an alle für die Hilfe;-)


Anmelden zum Antworten