Vokabel-Trainer



  • So sieht die Klasse im Moment aus:

    #include <vector>
    #include <string>
    #include <fstream>
    
    class Read_Write
    {
    	public:
    		void write(std::string& f, std::string& d, int unit);//um in eine Datei zu schreiben (unit für die Lektion, zu der die Vokabel gehört
    		void read();//liest alle Vokabeln aus der Datei in die vectoren
    		void read_unit(int unit);//liest nur die angegebene Lektion in die vectoren
    
    	private:
    		//Darin werden die Vokabeln gespeichert:
    		std::vector<std::string> fremdsprache;
    		std::vector<std::string> sprache;
    
    		std::fstream file;//um die datei zu öffnen und zu lesen
    
    };
    

    Soll ich lieber die Funktionen zur Abfrage als globale Funktionen machen? Oder in die Klasse Read_Write oder soll ich eine eigene Klasse erstellen?



  • SeppJ schrieb:

    Das klingt ehrlich gesagt alles nach schlechtem Stil. Guter Stil heißt nicht, alles in eine Klasse zu stopfen und erst recht nicht, alles zu vererben. Du meinst Java, nicht C++.

    lol, was hat das mit Java zu tun?



  • java4ever schrieb:

    lol, was hat das mit Java zu tun?

    public class Stack<E>
    extends Vector<E>
    

    http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html



  • theliquidwave schrieb:

    http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html

    Besser so als wie in C++. Der std::stack ist effektiv nutzlos.



  • Ich hab es jetzt so gelöst, da dies so näher an einem "Vokabelkasten" dran ist 😃 (std::vector<Vokabel>)

    #include <iostream>
    #include <string>
    
    class Vokabel
    {
    
    	public:
    		//get Methoden
    		std::string getDeutsch() const;
    		std::string getSprache() const;
    
    		//Um Instanzen zu ändern
    		void setDeutsch(std::string& d);
    		void setSprache(std::string& s);
    
    	private:
    		std::string Deutsch;
    		std::string Sprache;
    
    };
    
    //globale Funktionen
    //lesen und schreiben
    void read();
    void write(Vokabel& V, int unit);
    void read_unit(int unit);
    


  • lolipoplol schrieb:

    Ich hab es jetzt so gelöst, da dies so näher an einem "Vokabelkasten" dran ist 😃 (std::vector<Vokabel>)

    Das tönt gut!
    Einfach das Programm danach bauen, wie man als Mensch bevor man programmieren konnte, das angegangen wäre.

    Die Richtung mach mal weiter. Ist zwar bisher noch kacke, aber man kann's nicht übers Knie brechen.

    edit: Hey, Klasse Vokabelkasten! Wenn Du selber schon sagst, was es wird, nenne es doch auch so. Der Vokabelkasten HAT Vokabeln und KANN sich aus einer Datei laden und in dieselbe wegspeichern? Dann HAT er auch nen Dateinamen. Die Sprache gehörte dann aber zur Datei bzw zum Vokabelkasten? Sind die Lektionen Kästen? Oder nur die Sprachen? Denke, es ist Unfug, innerhalb einer Sitzung mehrerr Sprachen zu lernen. In einer Sitzung hat man einen (oder mehrere?) Vokabelkästen aktiv, aber wohl nicht zugleich mehrere Sprachen. Fragen über Fragen.

    edit2: ALLES nur Fragen, wie das Programm am Ende mit Dir interagieren soll. Wenn Du dazu einen Plan ersonnen hast, das Programmieren geht dann voll einfach. Weißt ja, was Du zu machen hast. Hab zum Abi auch mal so einen Vokabeltrainer gebaut. Krass: In Vokabeltest eine 1 zu schreiben ist Babyleicht und dauer nur ein viertel Stündchen Lernen.



  • so hab ich aber das Problem das ich nicht weiß, wie ich die Funktion read/read_unit implementieren soll... -.-
    Die Funktionen müssen ja immer nur eine Vokabel lesen und die einer Vokabel zuordnen. Dann muss die Funktion wissen wo sie stehen geblieben ist und die nächste Vokabel lesen...


  • Mod

    Wie würdest du denn eine Funktion schreiben, die einzelne Wörter liest?



  • SeppJ schrieb:

    Wie würdest du denn eine Funktion schreiben, die einzelne Wörter liest?

    Das bekomm ich schon hin aber die Funktion muss ja immer wissen bei welchem Wort sie stehengeblieben ist (da ja für jedes Vector<Vokabel> Element die Funktion neu ausgeführt wird und in einem Vector<Vokabel> ja nur eine Vokabel gespeichert werden kann...)
    Ich könnt einen Globalen Vector definieren, in dem die Funktion alle Vokabeln einliest und dann jedem Vector<Vokabel> ein Element von dem Globalen Vector zu weisen aber man soll ja keine Globalen Variablen verwenden.. 🙂


  • Mod

    lolipoplol schrieb:

    aber die Funktion muss ja immer wissen bei welchem Wort sie stehengeblieben ist (da ja für jedes Vector<Vokabel> Element die Funktion neu ausgeführt wird und in einem Vector<Vokabel> ja nur eine Vokabel gespeichert werden kann...)

    Ich verstehe weder, wieso das so sein sollte, noch wieso du denkst, dass das so sein sollte.

    Ich könnt einen Globalen Vector definieren, in dem die Funktion alle Vokabeln einliest und dann jedem Vector<Vokabel> ein Element von dem Globalen Vector zu weisen aber man soll ja keine Globalen Variablen verwenden.. 🙂

    Nein sicher nicht.

    Wenn du einzelne Wörter lesen kannst, was ist dann das Problem bei Wortpaaren?



  • Jetzt blick ich da nicht mehr so ganz durch -.-

    Wenn ich std::vector<Vokabel> benutze, kann ich die Funktion push_pack() nicht mehr benutzen O.o (muss ich selber definieren...)
    Und wenn ich so einlese:

    vector<Vokabel> m(10);
    
    	for(int i = 0; i < v.size(); i++)
    	{
    		read(m[i]);
    	}
    

    muss die Funktion read() immer wissen wo sie weiterlesen muss, weil sie ja sonst jedem element das selbe zu weist, so wies jetzt ist...

    Read fkt:

    void read(Vokabel& V)
    {
    	std::fstream file;
    	file.open("Vokabel.txt", std::ios::in);
    
    	std::string s;
    	std::string m;
    
    	while(file.good())
    	{
    		getline(file,s);
    
    		if(!isalpha(s[0]))
    		{
    			continue;
    		}
    
    		m = s.substr(0,s.find_first_of("-"));
    		V.setDeutsch(m);//speichert in jedem Vektor Element die letzte Vokabel die in der Datei steht (ist ja auch klar wegen der schleife :) aber ich weiß nicht wie ichs ändern kann -.-)
    
    		s = s.substr(s.find_first_of("-")+1);
    		V.setSprache(s);
    	}
    
    	file.close();
    }
    

  • Mod

    lolipoplol schrieb:

    Jetzt blick ich da nicht mehr so ganz durch -.-

    Wenn ich std::vector<Vokabel> benutze, kann ich die Funktion push_pack() nicht mehr benutzen O.o (muss ich selber definieren...)

    Nein, wieso sollte das so sein?

    Und wenn ich so einlese:

    vector<Vokabel> m(10);
    
    	for(int i = 0; i < v.size(); i++)
    	{
    		read(m[i]);
    	}
    

    muss die Funktion read() immer wissen wo sie weiterlesen muss, weil sie ja sonst jedem element das selbe zu weist, so wies jetzt ist...

    Das liegt da dran, weil deine read-Funktion jedes Mal die Datei neu öffnet, was ein sehr, sehr ungünstiges Design ist.

    Am Ende sollte das eigentlich so oder ähnlich aussehen:

    vector<Vokalbelpaar> vokabeln;
    ifstream datei("datei");
    for (Vokabelpaar vokabelpaar; datei >> vokabelpaar; )
      vokabeln.push_back(vokabelpaar);
    

    Somit musst du nur festlegen, was ein Vokabelpaar ist (für den Anfang bieten sich zwei strings an) und den operator>> dafür definieren (für den Anfang einfach zwei String lesen) und der Rest funktioniert automatisch.

    Ich habe gerade leider keine Zeit für ein Beispiel.

    Merke jedenfalls:
    Lesefunktionen lesen aus Streams! Um den Stream kümmert sich der Anwender der Lesefunktion. Eine Lesefunktion selber verwaltet keine Streams.



  • Nein, wieso sollte das so sein?

    Vokabel könnte CopyInsertable nicht erfüllen.

    Das ist aber recht unwahrscheinlich.



  • SeppJ schrieb:

    lolipoplol schrieb:

    Jetzt blick ich da nicht mehr so ganz durch -.-

    Wenn ich std::vector<Vokabel> benutze, kann ich die Funktion push_pack() nicht mehr benutzen O.o (muss ich selber definieren...)

    Nein, wieso sollte das so sein?

    Ich glaub, TE meint, dass er innerhalb der read Funktion nur auf ein Element Zugriff hat und nicht merh auf den vector.



  • ich glaub so weit bin ich mit C++ noch nicht -.-

    Hab den 1.Teil von "Der C++ Programmierer" durchgearbeitet :)aber muss doch erstmal noch weiter lernen -.-

    Ich schreibs doch erstmal in schlechtem C++ zu ende -.-

    #include <vector>
    #include <string>
    #include <fstream>
    
    class Vokabel
    {
    	public:
    		void write(std::string& f, std::string& d, int unit);
    		void read();
    		void read_unit(int unit);
    
    	private:
    		std::vector<std::string> fremdsprache;
    		std::vector<std::string> sprache;
    
    		std::fstream file;
    
    };
    

    Und noch die zwei Abfrage Methoden dazu 🙂

    Trotzdem Vielen Dank für eure Hilfe 🙂



  • std::fstream file;
    

    Wusst' ichs doch!

    Einen fstream als Member halten ist sehr schlechtes Design. Außerdem kannst du ihn nicht kopieren.

    Du musst dir unbedingt eine Lösung überlegen, die das vermeidet.



  • habs geändert 🙂 hab file jetzt in jede Methode die die Variable braucht drin 🙂



  • Jetzt übergibste den istream (ja, kein fstream, falls man aus strings, von der Konsole, etc. lesen will) noch als Argument der Funktion und schon ist die read() Funktion wesentlich flexibler.
    Denn der User deiner Klasse, sollte nicht die Klasse ändern müssen wegen etwas so banalem wie der Filename.


Anmelden zum Antworten