STL for_each mit list<EigeneKlasse>



  • Vokabeltrainer...

    Hier mein Problem:
    Möchte mir ein ein Vokabeltrainer im rahmen der schulaufgaben auf c++ schreiben. Rahmenbedingung es soll
    - möglichst eine Liste (STL) Container.
    - mit foreach und erase, und und und sich vertraut machen.
    - weitere Soll Sachen ist im Main Code beschrieben.

    Habe folgende Problem bei der Ausgabe mit for_each. Hierbei soll es mit for_each alle Elemente (Deutsch - English) aus List Vokabel die Reihe nach ausgeben.

    ===================

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <list>
    #include<algorithm>
    #include<vector>

    #include "Vokabel.h"
    #include "Ausgabe.h"

    using namespace std;

    void main()
    {
    list<Vokabel> lstVokabel;
    list<Vokabel> lstVokabelFalse;
    list<Vokabel> lstVokabelCorrect;

    list<Vokabel>::iterator iter;

    iter = lstVokabel.begin();
    // Vokabel aus Text Datei ins Vokabel Liste Einfügen
    lstVokabel.push_back(Vokabel("one", "ein"));
    lstVokabel.push_back(Vokabel("two", "zwei"));
    lstVokabel.push_back(Vokabel("three", "drei"));
    lstVokabel.push_back(Vokabel("four", "vier"));

    //Abfragen solange lstVokabel leer ist
    ??????????????????????????????????????????????????????????????????????????????????
    for_each(lstVokabel.begin(), lstVokabel.end(), iter->Foreach_Show); ////////FEHLER//

    }

    ============================================================

    #pragma once
    #include <string>
    using namespace std;
    class Vokabel
    {
    private:
    string _deutsch;
    string _english;

    public:
    Vokabel(void);
    ~Vokabel(void);
    Vokabel(string, string);

    void Show();
    void Foreach_Show(string, string);
    string Get_deutsch();
    void Set_deutsch(string);
    string Get_english();
    void Set_english(string);
    };

    ====================================================
    #include "Vokabel.h"
    #include <string>
    #include <iostream>
    using namespace std;

    Vokabel::Vokabel(void)
    {
    }
    Vokabel::Vokabel(string de, string en)
    {
    _deutsch = de;
    _english = en;
    }

    Vokabel::~Vokabel(void)
    {
    }

    void Vokabel::Show()
    {
    cout<< _deutsch << " " << _english<<endl;
    }
    void Vokabel::Foreach_Show(string de, string en)
    {
    cout<< de << " " << en <<endl;
    }

    string Vokabel::Get_deutsch()
    {
    return _deutsch;
    }
    void Vokabel::Set_deutsch(string de)
    {
    _deutsch = de;
    }

    string Vokabel::Get_english()
    {
    return _english;
    }
    void Vokabel::Set_english(string en)
    {
    _english = en;
    }



  • da die member funktion void Vokabel::Foreach_Show(string de, string en) prarmeter hat, kannst du dies nich al funktor verwenden

    was passiert wenn du:

    for_each(lstVokabel.begin(), lstVokabel.end(), Vokable::Show);
    

    machst geh das?



  • Const-Correctness (benötigt u.a. für operator<<) und Übergabe per const-referenz.

    class Vokabel 
    { 
    private: 
    	string _deutsch; 
    	string _english; 
    
    public: 
    	Vokabel(); 
    	~Vokabel(); 
    	Vokabel(const string&, const string&); 
    
    	void Show() const; 
    	string Get_deutsch() const;
    	void Set_deutsch(const string&);
    	string Get_english() const;
    	void Set_english(const string&);
    }; 
    
    Vokabel::Vokabel() 
    { 
    } 
    
    Vokabel::Vokabel(const string& de, const string& en) 
    { 
    	_deutsch = de; 
    	_english = en; 
    } 
    
    Vokabel::~Vokabel() 
    { 
    } 
    
    void Vokabel::Show() const
    { 
    	cout<< _deutsch << " " << _english<<endl; 
    }
    
    string Vokabel::Get_deutsch() const
    { 
    	return _deutsch; 
    } 
    void Vokabel::Set_deutsch(const string& de) 
    { 
    	_deutsch = de; 
    } 
    
    string Vokabel::Get_english() const
    { 
    	return _english; 
    } 
    void Vokabel::Set_english(const string& en) 
    { 
    	_english = en; 
    } 
    
    ostream& operator<<(ostream& os, const Vokabel& vokabel)
    {
    	os << vokabel.Get_deutsch() << ' ' << vokabel.Get_english() << endl;
    	return os;
    }
    

    Die Methode Foreach_Show erscheint mir unangebracht.
    Das Programm:

    int main()
    {
        list<Vokabel> lstVokabel; 
    	list<Vokabel> lstVokabelFalse; 
    	list<Vokabel> lstVokabelCorrect; 
    
    	list<Vokabel>::iterator iter; 
    
    	iter = lstVokabel.begin(); 
    	// Vokabel aus Text Datei ins Vokabel Liste Einfügen 
    	lstVokabel.push_back(Vokabel("one", "ein")); 
    	lstVokabel.push_back(Vokabel("two", "zwei")); 
    	lstVokabel.push_back(Vokabel("three", "drei")); 
    	lstVokabel.push_back(Vokabel("four", "vier")); 
        // Ausgabe über std::copy, ostream_iterator und operator<<
    	std::copy(lstVokabel.begin(), lstVokabel.end(), ostream_iterator<Vokabel>(cout, "\n"));
        // Ausgabe über for_each und Vokabel::Show
    	std::for_each(lstVokabel.begin(), lstVokabel.end(), mem_fun_ref<void, Vokabel>(&Vokabel::Show));
    


  • Danke erstmals für die reichlichen Antworten.

    Hallo BorisDieKlinge. Also dein Vorschlag hatte ich auch schon vorgenommen. Das ging aber nicht. Aber wie meinst du es mit Funktor. Also ich verstehe nicht genau was das sein soll. Foreach läuft durch den Container und bearbeitet jeder Element mit dem Funktor. Den Syntax ist mir erst bei benutzung foreach bekannt.

    Airdamn
    Dein Lösung scheint mir auch sehr logisch zu sein. werde selbst versuchen. Denn im grunde genommen konnte de STL For_each nicht wissen was man ausgeben möchte, da es sich hier um ein eigene Klasse handelt. Daher ein explizite Anweisung.
    Auf dem ersten blick versteht ich immer noch nicht genau wie ich es implementieren soll. Ich werde mir mühe geben.

    Danke ...

    Das Programm ist so weit komplett fertig. Hatte über while schleife ausgegeben.
    Wollte aber dennoch mit foreach testen.

    in vielen büchern und auf google sind solche fälle wie die meiner leider nicht dokumentiert. Meist immer list<int> list<string> aber nie eigeneklasse. Schade eigentlich, denn das hätte man gebraucht. Bsp. wie sortiere ich dann meine liste (mit eigenklasse), oder wie ...
    vielleicht kennt ihr irgendwo so ein fall dass ich mal als beispiel anschauen kann.



  • Nun beim sortieren kannst Du einen eigenen comparator verwenden,
    oder entsprechend operator< überladen.



  • Terrakotta001 schrieb:

    in vielen büchern und auf google sind solche fälle wie die meiner leider nicht dokumentiert. Meist immer list<int> list<string> aber nie eigeneklasse. Schade eigentlich, denn das hätte man gebraucht. Bsp. wie sortiere ich dann meine liste (mit eigenklasse), oder wie ...
    vielleicht kennt ihr irgendwo so ein fall dass ich mal als beispiel anschauen kann.

    hast du ein Glück, dass ich heute so etwas geschrieben habe bzw. vorhin:

    // Klasse Bruch
    class Bruch
    {
        private:
            int za;         // Zaehler
            int ne;         // Nenner
        public:
            // Standard-konstruktor
            Bruch(){za = 0; ne = 1;}
    
            // Konstruktor mit Parametern
            Bruch(int z, int n){ if (n>0) {za=z; ne=n;}}
    
            // Ausgabe des Bruches
            friend ostream & operator<<(ostream & out, const Bruch b)
                {out << b.za << "/" << b.ne; return out;}
    };
    
    int main()
    {
    
        cout << "Listen: " << endl;
        // Erstellen von 3 Bruechen
        Bruch b1(1, 2);
        Bruch b2(1, 4);
        Bruch b3(6, 8);
    
        // Beispiel für Liste
        // Anlegen einer STL-Liste
        list<Bruch> bruchlist;
    
        // Anfuegen von Bruechen ans Ende der Liste (hintereinander)
        bruchlist.push_back(b1);
        bruchlist.push_back(b2);
    
        // Anfuegen von Bruechen an den Anfang der Liste (hintereinander)
        bruchlist.push_front(b3);
    
        // Festlegen eines Iterators
        list<Bruch>::iterator it;
    
        // Vom Anfang bis zum Ende der Liste mit Schrittweite ++
        for (it=bruchlist.begin();it != bruchlist.end(); it++)
        {
            // gebe Iterator aus
            cout << *it << endl;
        }
    }
    

    Schau dir mal die Operator-Überladung für den Bruch an.
    Wenn du so etwas Ähnliches für dein Problem verwendest, kommst du evtl. zu einer Lösung.
    Das hat nämlich den Vorteil, dass du einfach sagen kannst gib iterator aus, denn
    die Klasse Bruch hat für sich selbst eine Methode zum ausgeben.



  • Danke Danke. Den Code abschnitt hat mir viel geholfen. kommende Dienstag schreibe ich schon die klausur Informatik. Habe der ganzen Semester sich mit ADT Liste Binär Baum und solche sachen umgeschlagen. Jetzt heiss es man konnte auch STL verwenden.
    Mir fehlt noch erfahrung an STL geschichte. Es hilft mir viel wenn ich mir ein Programm mit STL Anwendung lese und mir darau seine tücken, vorteile und Ideen dazulerne.
    kennt ihr vielleicht free source code, bei denen es teilweise mit STL arbeitet?.

    Vorerst danke für den Code ... . Das hat mir viel geholfen.
    sortieren hat nun auch mit operator > geklappt. auch das erase verbirgt manche Tücken.

    while ... schleifen bis lstVokabel leer ist
    {
    if (antwort == itVokabel->Get_english())//Richtige Antwort => ins Topf lstVokabelCorrect
    {
    cout <<"Computer: richtig"<<endl;

    lstVokabelCorrect.push_back(*itVokabel); //Hier schieben zu Richtig beantwortete Topf
    itVokabel = lstVokabel.erase(itVokabel); //Hier Löschen
    listAnfang = (itVokabel == lstVokabel.end());
    }
    else //Falsch beantwort => ins Topf lstVokabelFalse
    {
    cout <<"Computer: falsch; Richtig waere "<< itVokabel->Get_english() <<endl;
    lstVokabelFalse.push_back(*itVokabel); //Hier schieben zu Falsch beantwortete Topf
    itVokabel = lstVokabel.erase(itVokabel); // Hier Löschen
    listAnfang = (itVokabel == lstVokabel.end());
    }
    }



  • Ich kann mri nicht vorstellen, dass ihr in Datenstrukturen ewig lang an Listen und co euch versucht um in der Klausur nen STL_Container zu verwenden.
    Bei uns war das jedenfalls nicht derfall. Wir durften nen umfangreichen Baum schreiben.



  • Wir nen Kernel.



  • das wäre auch ne möglichkeit. 😞
    Ich hoffe mal nicht. Man hat nur 3 stunden zeit sich ein komplette Lösung zu programmieren.
    Wieviel Zeit hattest du? Wir habe 3 stunden. Das ist nicht viel.
    Wenn man bedenkt, wenn du kompilier fehler hast. dies zu beheben, dauert 5-10 minute. das hat man nicht wenig fuer 3 stunden.
    wie sah die anforderungen deine Klausur aus?
    unser letztes Praktikum hatten wir auch baum produziert.



  • Also wir hatten 120 Minuten, sprich 2 Stunden.
    2 teilige Prüfung: Praxis + Theorie

    Im Praxisteil wurde der Baum abverlangt.
    Er sollte Werte aufnehmen können, ausgeben können
    (Präfix, Infix und Postfix (also rekursiv)), und den Baum komplett löschen können.

    Dazu kam noch der Theorie-Teil mti Fragen bezüglich Datenstrukturen.


Anmelden zum Antworten