fstream: Vokabeltrainer: Einlesung von text.txt funktioniert nur teilweise.



  • Die Streuung der Hashfunktion zur zufälligen Reihenfolge der Vokabeln zu verwenden finde ich ziemlich panne. 🙄
    Vor allem so wie du es machst, du nutzt die Map ja nichtmal zum Lookup.

    std::vector nehmen, die Pairs rein und std::random_shuffle. Fertig.



  • "Panne" ist, wenn man Wörterbuch-Aufgabenstellungen nicht mit Dictionaries löst und Anfängern, die wie hier Programmieren durch Ausprobieren praktizieren, mit allgemeinen Weisheiten über Vectoren kommt.
    Ich habe mal gehört, dass sich Daten zur Laufzeit eines Programms auch ändern können, und was machst du dann?
    Nach jedem Einfügen/Löschen nochmal Shuffle und den Gesamtdatenbestand anfassen?
    Und nichtindiziertes Löschen aus Vectoren praktizierst du wohl auch sehr gern.
    Natürlich kann man mit Vectoren auch ziemlich Ähnliches wie mit Dictionaries erreichen, man muss es aber nicht; und insbesondere nicht für Anfänger.
    Mit solchen "Qualitäts"vorstellungen bei C++ Datenstrukturen für Anfänger kannst du den üblichen Tutorialschreiberlingen/Fachbuchautoren/Hochschuldozenten/push_back-Fetischisten/... die Hand reichen.



  • Wutz schrieb:

    Nach jedem Einfügen/Löschen nochmal Shuffle und den Gesamtdatenbestand anfassen?

    Die unordered_map verändert die Reihenfolge der ursprünglichen Elemente dann auch nicht (immer), also müsste push_back reichen. Wenn ein mischen gewünscht ist, geht das mit (genau) einer unordered_map gar nicht.

    Wutz schrieb:

    Und nichtindiziertes Löschen aus Vectoren praktizierst du wohl auch sehr gern.

    swap(vec[i], vec.back()); vec.push_back();
    

    Wutz schrieb:

    Natürlich kann man mit Vectoren auch ziemlich Ähnliches wie mit Dictionaries erreichen, man muss es aber nicht; und insbesondere nicht für Anfänger.

    Die Dinger sind grundverschieden. Vector hat eine feste Reihenfolge, unordered_map ist halb-zufällig und kaum beeinflussbar.

    Mit solchen "Qualitäts"vorstellungen bei C++ Datenstrukturen für Anfänger kannst du den üblichen Tutorialschreiberlingen/Fachbuchautoren/Hochschuldozenten/push_back-Fetischisten/... die Hand reichen.

    dito



  • pfann schrieb:

    swap(vec[i], vec.back()); vec.push_back();
    

    Du meinst pop_back 😉

    @Wutz: Da du immer von Dictionaries redest, zeugt dass eher davon, dass du von einer Sprache wie C# oder Java kommst.

    Aber für das bisschen, was der TE hier erwartet, da reicht sowohl ein vector<pair<string, string> als auch eine map<string, string> als auch eine unordered_map<string, string>.

    Wie wir alle wissen hat ejde dieser Strukturen seinen Vor- oder Nachteil. Aber gerade weil eben so wenig Rahmenbedingungen bekannt sind (oder auch sogar nur vorhanden/verlangt), reicht das doch.



  • #include <iostream>
    #include <vector>
    #include <string>
    #include <fstream>
    //#include <random> //c++ 11
    #include <cstdlib>
    #include <ctime>
    
    #define ENG 0
    #define DEU 1
    
    using namespace std;
    
    int trainer(const string language, const string s1){
        unsigned int right_w(0), false_w(0);
    
        ifstream in;
        char c;
        string wordCache;
        vector < string > current;
        vector < vector < string > > vocab;
    
        in.open(s1.c_str()); // Open the file in read-only mode
        if (!in.is_open()) return 1; // Check whether it was opened successfully
    
        while ((c = in.get()) != -1) { // Walk through the file
            if (c == '\t' || c == '\n') { // Delimiter
                current.push_back(wordCache); // Add cached text to the array
                wordCache = ""; // Reset cache
            }
            else {
                wordCache += c; // Otherwise just append the current character to our word cache
            }
            if (c == '\n') { // In case we hit a newline,
                vocab.push_back(current); // Add the cached vocab pair to the vocab array
                current.clear(); // And don't forget to clear the vocab pair
            }
        }
    
        in.close();
    
        int v_rand;
        srand(time(NULL));
    
        string mem;
        if(language == "de"){        
            for(;;){
                v_rand = rand() % (vocab.size())+0;
                cout << "Übersetze das Wort. STRG+D = Abbruch! Ausgangssprache [ " << language << " ] : "
                     << vocab.at(v_rand).at(DEU) << endl;
                if(!(cin >> mem)) { break; } //Abbruch mit STRG+D(unter linux)
                if(mem == vocab.at(v_rand).at(ENG)){
                    cout << "Richtig!" << endl;
                    ++right_w;
                }
                else{
                    cout << "Falsch!\t" << "Die richtige Vokabel lautet: " << vocab.at(v_rand).at(ENG) << endl;
                    ++false_w;
                }
            }
        }
        else if(language == "en"){
            for(;;){
                v_rand = rand() % (vocab.size())+0;
                cout << "Übersetze das Wort. STRG+D = Abbruch! Ausgangssprache [ " << language << " ] : "
                     << vocab.at(v_rand).at(ENG) << endl;
                if(!(cin >> mem)) { break; } //Abbruch mit STRG+D(unter linux)
                if(mem == vocab.at(v_rand).at(DEU)){
                    cout << "Richtig!" << endl;
                    ++right_w;
                }
                else{
                    cout << "Falsch!\t" << "Die richtige Vokabel lautet: " << vocab.at(v_rand).at(DEU) << endl;
                    ++false_w;
                }
            }
        }
        cout << "Ergebnis:\trichtig: " << right_w << "\tfalsch: " << false_w << endl;
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        string s1;
        if(argc > 1){
            s1 = argv[1];
        }
        if(s1.empty()){
            cout << "Benutze: ./Vokabeltrainer <VOKABELQUELLE.txt>" << endl;
            return 3;
        }
    
        string lang;    
        cout << "Wähle die Sprache. [en] für English->Deutsch. [de] für Deutsch->Englisch" << endl;
    
        while(cin >> lang){
            if(lang == "de")
                break;
            else if(lang == "en")
                break;
            else{
                cerr << "FEHLER: Falsche Eingabe. Eingabe muss [en] oder [de] lauten!" << endl;
                continue;
            }
        }
        trainer(lang, s1);
        return 2;
    }
    

    Problem gelöst. Programm läuft. Das ist für mich die beste Lösung. std::map und std::unordered_map habe ich natürlich auch ausprobiert. Da hatte ich aber später Probleme mit. Mit <random> habe ich mich kurz beschäftigt. Ich fand aber, dass rand() die bessere und einfachere Lösung für mein Programm war.
    Sooo ich mache jetzt lieber in meinem Buch weiter, damit ich das nächste mal wenn ich wieder ein Problem haben sollte, nicht mit so einem Halbwissen wiederkomme... Danke an alle die mir helfen konnten.


Anmelden zum Antworten