fstream - getline Problem



  • Leider läuft mir grad die Zeit davon und ich bin immer noch nicht schlauer geworden :(.
    Kann mir nicht einer den Code von der Vokabelabfrage aus einem Textdokument geben?
    Ich weiß schon, dass ich dabei nichts lerne, habe aber vor, den ganzen Kram nochmal zu lernen, aber zusammen mit einem Buch und ohne Onlinetutorials, bei denen ich aber auch nicht weit gekommen bin, aufgrund der Zeit wie gesagt.
    Ich wäre euch sehr dankbar, wenn ihr "meine Bitten erhört" 😉 und mir den Quellcode für eine solche Abfrage geben könnt.



  • Ich will ja mal nicht so sein..

    #include <iostream>
    #include <fstream>
    #include <map>
    #include <string>
    
    int main()
    {
    	typedef std::pair<std::string,std::string> vok_pair;
    	typedef std::map<std::string,std::string>::iterator vok_iter;
    
    	std::ifstream in ("vok_db.txt");
    	std::map<std::string, std::string> voks;
    	vok_pair pair;
    
    	//Einlesen
    	while (in >> pair.first)
    	{
    		in >> pair.second;
    		voks.insert (pair);
    	}
    
    	//Hier die Ausgabe
    	for (vok_iter it = voks.begin ();it != voks.end ();it++)
    	{
    		std::cout << "Deutsch: " << it->first << " Englisch: " << it->second << std::endl;
    	}
    
    	//Zufälliger Indes aus dem Vokabeln
    	int random = rand ()%voks.size ();
    
    	vok_iter it = voks.begin ();
    	while (random--) it++;
    
    	std::cout << "Zufaellige Auswahl:" << std::endl;
    	std::cout << "Englisch: " << it->second << std::endl;
    
    }
    

    Analysieren und für deine Zwecke umbauen musst du aber noch selber. 😉



  • Danke für deine Hilfsbereitschaft.
    Ist aber zum Glück nicht mehr nötig.
    Denn ich habe jetzt etwas geschrieben,was eigentlich Strukutur hat.
    Meine Idee war es jedoch, in jede gerade Zeile eine deutsche Vokabel und andersrum zu schreiben.
    Habe auch einen Code geschrieben der das so ausliest:

    cout<<"Wenn du verlassen willst, gebe bitte bei Aufforderung zur deutschen Vokabel EXIT ein.\n";
    				cout<<"Bitte kein Umlaute benutzen! Schreibe ae, oe, ue, sz!\n";
                           ifstream InFile; 
                           InFile.open(pszDATEI);//dann öffnen
    				       if (!InFile)       
           				   {
                              cout << "Fehler beim Oeffnen der Datei!\n"; 
                              exit(1);                                    
                           }
                           vector<std::string> vokabels2; // Dynamisches Array 
                           string tstr;                                  
                           while(getline (InFile,tstr))               
                           {
                           vokabels2.push_back(tstr);                    
                           }              
                           srand( (unsigned) time(NULL) ) ; 
                           size_t size = vokabels2.size();                 
                           int zufallZ = 1 + ( rand() % 145 ) ;
                           int zufall2 = zufallZ * 2;
                           cout << vokabels2[zufall2] << endl; 
                           char check[200]=vokabels2[zufall2] + 1;
                           char abfrage [200];
                           if(check==abfrage) {
                           cout<<"Richtig!!!\n";
                           }
    

    In meinen Text-Dokument sieht es so aus:

    test1
    test2
    test3
    test4
    ...
    

    Ich sehe eigentlich keinen Fehler, auch nach mehrmaligem Lesen, jedoch bezweckt mein Programm nur einen Absturz 😮 .
    Wo liegt denn hier mein Fehler?
    Edit: Auch mein Compiler zeigt keinen Fehler an.
    Kann das vielleicht daran liegen, dass ich eine zufällige Zahl zwischen 0 und 145 generiere, obwohl ich gar keine 290 Zeilen habe? Wie kann ich automatisch die Zeilennazahl ermitteln?(automatisch, da sie sich ja ständig ändert)



  • Hier:

    Chrisl schrieb:

    srand( (unsigned) time(NULL) ) ; 
                           size_t size = vokabels2.size();                 
                           int zufallZ = 1 + ( rand() % 145 ) ;
                           int zufall2 = zufallZ * 2;
                           cout << vokabels2[zufall2] << endl; 
                           char check[200]=vokabels2[zufall2] + 1;
                           char abfrage [200];
                           if(check==abfrage) {
                           cout<<"Richtig!!!\n";
                           }
    

    Was genau soll denn der Kram mit dem char check? Macht das so wirklich Sinn?
    Was passiert, wenn die Zufallszahl größer ist, als die Anzahl der Strings in Deinem Vektor?
    Du hast also z.B. 50 Strings in Deinem Vektor. Jetzt knobelt der Generator die Zahl 70 aus (und das auch noch * 2, wieso eigentlich?). Jetzt greifst Du also auf vokabels2[140] zu, obwohl Du nur bis max. vokabels2[49] gehen dürftest...



  • Das mit dem char check soll die passende Vokabel zu der ausgelesenen Vokabel sein.
    Mit dieser wird ja dann die Eingabe des Benutzer verglichen.
    Was du ansprichst, ist ja genau mein Problem. Man kann bei meinem Programm auch noch Vokabeln hinzufügen, also statt 50 strings sind es plötzlich 60. Dann werden die neuen Vokabeln ja gar nicht abgefragt. Deswegen dachte ich, lieber eine größere Zahl beim Zufallswert schreiben als eine passende, die nachher zu klein ist.
    Könnte man die Zeilenanzahl eines Textdokuments ermitteln, wäre mein Problem ja wahrscheinlich gelöst.



  • Wie wäre es mit sowas:

    srand(time(NULL));
    size_t abfrage_index = (rand() * rand()) % vokabels2.size();
    std::cout << vokabels2[abfrage_index] << '\n';
    //...
    

    Nachtrag: Guck Dir vielleicht doch noch mal die Lösung von drakon an. Er hat Dir schon eine Menge gute Tips gegeben.



  • Danke, hab mittlerweile auch herausgefunden, dass nur das Grund für den Absturz war.
    Obwohl da noch ein paar andere Fehler waren, die ich jetzt berichtigt habe.
    Das Problem bei Drakon's Lösung ist leider die, dass ich noch nicht soweit bin und viele Dinge nicht verstehe. Deswegen kann ich es auch schlecht "analysieren und für [m]eine Zwecke umbauen."
    Zu meinen Glück habe ich aber noch bis Freitag Zeit und denke schon, dass ich mit meiner Lösung, die bestimmt sehr umständlich ist, alles hinbekomme.



  • Neues Problem 😡
    Ich weiß nicht, wie ich zwei Zeilen vergleichen soll, obwohl ich eigentlich keinen Fehler sehe. Denn ich lese eine zufällige Zeile aus, die dann mit der nächsten Zeile verglichen werden soll.
    Das klappt aber leider nicht ganz, denn ich kann vokabels2[check] irgendwie nicht in eine if-Verzweigung einbauen:

    ifstream InFile; //falls Datei vorhanden
                           InFile.open(pszDATEI);//dann öffnen
    				       if (!InFile)   
           				   {
                              cout << "Fehler beim Oeffnen der Datei!\n"; 
                              exit(1);                                    
                           }
                           vector<std::string> vokabels2;
                           string tstr;                                
                           while(getline (InFile,tstr))              
                           {
                           vokabels2.push_back(tstr);                   
                           }            
                           srand(time(NULL));
                           size_t size = vokabels2.size();                
                           size_t abfrage_index = (rand() * rand()) % vokabels2.size();
                           int zufall2 = abfrage_index * 2;
                           int check;                       
                           check=zufall2 -1;
                           cout << vokabels2[abfrage_index] << '\n'; 
                           int abfrage;
                           cin>>abfrage;
    
                           if(abfrage==check) {
                                              cout<<"Richtig\n";
                           }
                           if(abfrage!=check) {
                                              cout<<"Richtig falsch\n";
                           }
    

    Das ist mein momentanes Programm, wo jedoch ständig die Fehlermeldung in der Konsole auftaucht, abfrage!=check, obwohl ich schon alles ausprobiert habe.
    Und statt check kann ich aber auch nicht vokabels2[check] in der if-Verzweigung verwenden, da wie oben angesprochen, dann der Compiler einen Fehler meldet.



  • Also dein Code ist (wiedereinmal) völlig Wirr und ich kann nicht so ganz draus blicken, was du dir dabei denkst.. 🙄

    Du erstellst zwar ein ifstream, aber benutzt ihn nirgends.
    Du erstellst size_t size,aber benutzt ihn nirgends.

    size_t abfrage_index = (rand() * rand()) % vokabels2.size();
    

    Das verstehe ich auch nicht ganz, was du da vorhast.
    Und was Abfrage und Check miteinander zu tun haben sehe ich auch nicht ganz.

    Wenn du 2 Strings miteinander vergleichen willst, kannst du das ganz einfach mit dem = Operator machen..

    btw:
    In meine Beispiel hat es nichts, was du nicht selber auch schon gebraucht hast. Im übrigen wären das ja relativ einfache Sachen.

    Das einzige, was dich verwirren könnte ist das hier:

    typedef std::pair<std::string,std::string> vok_pair;
        typedef std::map<std::string,std::string>::iterator vok_iter;
    

    Was aber nicht weiter kompliziert ist. hier ersetze ich lediglich die komplizierte Schreibweise für einen Iterator und für ein pair, um mir ein wenig Schreibarbeit erspare.



  • Jawoll, ich habe jetzt doch deinen Code genommen, noch ein bisschen verändert und siehe da:
    Alles klappt so, wie ich es mir vorgenommen habe 🙂
    Eine Riesendank an alle, die mir geholfen haben und vor allem an dich, Drakon ;).



  • So ein Zufall auch.
    ich möchte mir auch ein Vokabeltrainer ganz in deinem Stil auf C++ schreiben. Einlesen in die Liste ist klaro. aber eins komme ich nicht weiter.
    Wie weit bist du schon? habe noch probleme bei der foreach schleife. Und zwar

    ...

    Möchte ich mir ein ein Vokabeltrainer im rahmen der schulaufgaben auf c++ schreiben. Rahmenbedingung es soll
    - möglichst eine Liste (STL) Container.
    - sich 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.
    Vielleicht konnte jemand mir dann mal weiter helfen ...

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

    #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;
    }


Anmelden zum Antworten