Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů



  • Gude ich habe ein Programm geschrieben welches B├╝cher hinzuf├╝gen sowie ausgeben und l├Âschen soll ich hab einen Fehler wo ich das Buch einlesen m├Âchte von dem User in der Zeile (81) und wei├č nicht genau wo das Problem liegt k├Ânnte mir hier bitte jemand helfen ein Riesen Dankesch├Ân schon voraus (ich programmiere Objekt orientiert) ­čśů­čść

    //
    //  main.cpp
    //  buch
    
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    //Klasse Buch
    class buch {
    
    private:
    
        string title;
        string autor;
        int jahr;
        int seitenanzahl;
        string kategorie;
    
    public:
    
        //Standartkonstruktor:
        buch();
    
        //Algemeiner Konstruktor
        buch(string t, string a, int j, int s, string k);
    
        //Kopierkonstruktor:
        buch( buch const & buch1);
    
        //Ausgabe methode
        void print();
        
        //Menue methode
        void menue();
    };
    
    
    
    //Buch cpp
    //Standartkonstruktor dekleration
    buch::buch() {
    
        title = "Leer ";
        autor = " Leer";
        jahr = 0;
        seitenanzahl = 0;
        kategorie = "Leer";
    }
    
    
    
    //Allgemeinerkonstruktor dekleration
    buch::buch(string t, string a, int j, int s, string k) {
    
        title = t;
        autor = a;
        jahr = j;
        seitenanzahl = s;
        kategorie = k;
    }
    
    
    //Ausgabe auf dem Display:
    void buch ::print() {
    
        cout << "Titel: " << title << endl << "Autor: " << autor << endl << "jahr: "
        << jahr << endl << "Seitenanzahl: " << seitenanzahl << endl << "Kategorie: "
        << kategorie << endl << endl;
    }
    
    //Die Methode men├╝ defenieren
    void buch ::menue(){
        
        //Vektor erstellen:
        vector<buch> buch_vector;
        
        //Buch hinzuf├╝gen
        for(int i = 1; i < 5; i++){
            cin >> buch_vector[i];
                    
        }
          }
    
    
    
    int main(){
    
        //Hier wird der Allgemeiner Konstruktor aufgerufen
        buch k ("Harry", " Potter ", 1998, 1050, " Magie");
        k.print();
        
        //Hier wird der Standartkonstruktor aufgerufen
        buch l;
        l.print();
        
        //Hier wird der Kopierkonstruktor aufgerufen
        buch m;
        m = k;//Objkt k in m objkt kopiert
        m.print();
    
    
        
        return 0;
    
    }
    


  • Du erstellst mit vector<buch> buch_vector einen leeren vector, und da kannst du dann keine Werte an die Indizes schreiben.
    Benutze stattdessen push_back(...) (also erst Wert in temp. buch einlesen und dann hinzuf├╝gen).

    PS: Und ├╝berlege dir noch mal den Kommentar bei

     //Hier wird der Kopierkonstruktor aufgerufen
    buch m;
    


  • *Achso verstehe meinst du ich soll es so machen?

    buch_vector.push_back(i);
    

    aber das klappt auch nicht... ­čÖü
    ich bekomme diese Fehlermeldung:
    No matching member function for call to 'push_back'*

    hmm was ist an dem Kommentar falsch mit dem aufrufen des Kopierkonstruktors?


  • Mod

    In einen Buchvector kann man ja auch schlecht ein Zahl wie i einf├╝gen. Vielleicht solltest du es lieber mit einem Buch versuchen?



  • Eine ganz andere Frage: warum ist die Funktion "menue" eine Methode der Klasse "Buch"? Dein "Buchmen├╝" enth├Ąlt eine Liste von B├╝chern. Listen von B├╝chern vorzuhalten ist aber eher die Aufgabe einer Bibliothek als die Aufgabe eines Buches selbst.



  • @wob achso dann habe ich die Aufgabenstellung nicht ganz verstanden ­čśę
    Danke dir ­čśü ­čĹŹ­čĆŻ



  • @SeppJ

    Hmm okay ich habe es damit versucht schau so:

     buch_vector.push_back(buch);
    

    aber es klappt immer noch nicht...



  • @adii950 sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    @SeppJ

    Hmm okay ich habe es damit versucht schau so:

     buch_vector.push_back(buch);
    

    aber es klappt immer noch nicht...

    Hast du eine Variable mit dem Namen buch?

    Oder hei├čen die k, l oder m?



  • @DirkB ein die klasse hei├čt buch



  • @adii950 sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    @DirkB ein die klasse hei├čt buch

    Willst du die ganze Klasse in den Vektor schieben oder nur die Inhalte von einer Variablen?



  • Wie initialisierst du denn das buch-Objekt?
    ├ťberlege dir, welchen Konstruktor du daf├╝r ben├Âtigst (so wie deine Klasse jetzt definiert ist) und was du dann noch coden mu├čt.

    @adii950 sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    hmm was ist an dem Kommentar falsch mit dem aufrufen des Kopierkonstruktors?

    Du rufst dort den Standardkonstruktor auf, und in der anschlie├čenden Zeile den Zuweisungsoperator =.
    Der Kopierkonstruktor wird bei buch m(k); aufgerufen (da du ihn aber nur deklariert, aber nicht definiert hast, k├Ąme eine Compilerfehlermeldung). Daher schreibe in der Klasse:

    buch(buch const & buch1) = default;
    


  • @DirkB die Inhalte in der Klasse buch damit ich verschiedene B├╝cher in den Vektor speichern kann und sp├Ąter das ausgeben sowie auch l├Âschen kann



  • Eine Klasse ist nur eine Vorlage, du ben├Âtigst schon ein konkretes Objekt (in deinem Beispiel z.B. die Variablen mit Namen k, l oder m) - daher schrieb ich ja auch:

    also erst Wert in temp. buch einlesen und dann hinzuf├╝gen

    damit meinte ich nat├╝rlich

    also erst Wert in temp. buch-Objekt (bzw. Variable) einlesen und dann hinzuf├╝gen

    Besser ist es, du schreibst erst einmal eine freie Funktion zum Einlesen eines buch-Objekts, welche du dann von deiner Funktion menue (btw.: komischer Name daf├╝r) aus aufrufen kannst, um einen vector zu erstellen.


    Die bessere L├Âsung w├Ąre die ├ťberladung der Stream-Operatoren <</ >>, aber soweit bis du wohl noch nicht (mit deinem Lernmaterial).



  • @Th69 sagte:

    Die bessere L├Âsung w├Ąre die ├ťberladung der Stream-Operatoren <</ >>, aber soweit bis du wohl noch nicht (mit deinem Lernmaterial).

    Wenn man das mal w├╝sste, zumindest wei├č er wohl, dass es sowas gibt:

    @adii950 sagte:

    //Vektor erstellen:
    vector<buch> buch_vector;
    
    //Buch hinzuf├╝gen
    for(int i = 1; i < 5; i++){
        cin >> buch_vector[i];


  • willst Du das Ganze nicht besser so l├Âsen:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    struct buch
    {
    string titel;
    string autor;
    int jahr;
    int seitenanzahl;
    string kategorie;	
    };
    
    void neu(vector<buch>& v)
    {
    buch b;
    
    cout << "Bitte titel eingeben:\n" ;
    getline(cin , b.titel);
    cout << "Bitte autor eingeben:\n" ;
    getline(cin , b.autor);
    //code
    v.push_back(b);
    }
    
    void ausgabe(vector<buch>& v)
    {
    for(buch& b: v)
    	{
    	cout << b.titel << "\n";
    	cout << b.autor << "\n";
    	//code	
    	cout << "\n";
    	}
    }
    
    void loeschen(vector<buch>& v)
    {
    //code
    }
    
    int main()
    {
    
    vector<buch> verzeichnis;
    
    char cha;
    string str;
    
    while(cha != 'e' )
    	{
    	cout << "Bitte eingeben: e(f├╝r ende), n(eu), a(usgabe) oder l(oeschen)\n" ;
    	getline(cin , str);	
    	if(str.length() > 1)
    		continue;
    	else
    		cha = str[0];
    	switch (cha)
    		{
    		case 'e':
    		break;
    		case 'n':
    		neu(verzeichnis);
    		break;
    		case 'a':
    		ausgabe(verzeichnis);
    		break;
    		case 'l':
    		loeschen(verzeichnis);
    		break;
    		}
    	}
    
    return 0;
    }
    
    


  • @yxcvbn In wie weit besser?

    Also, warum bekommt eine Funktion die "neu" hei├čt, eine Referenz auf einen Vektor ├╝bergeben und gibt nichts zur├╝ck?
    Warum macht eine Funktion die neu hei├čt Ausgaben auf std::cout
    Warum ├╝bernimmt eine Funktion die ausgabe hei├čt, eine Referenz und d├╝rfte somit ├änderungen an der Datenstruktur vornehmen.

    Warum ist ein B├╝cherverzeichnis ein Vektor und keine eigene Klasse, die Verzeichnis Funktionalit├Ąten wie hinzuf├╝gen, l├Âschen, vlt irgendwann mal nach bestimmten Sachen suchen usw. kapseln kann?

    Hier wurde schon von ├ťberladung der Stream Operatoren geschrieben, warum wurde das nicht gemacht, dann kann man sich unabh├Ąngig von std::cin und std::out machen und Funktionalit├Ąten auch automatisiert testen. Und, vor allem, in eine "echten" Anwendung w├╝rde man so ein Verzeichnis ja wahrscheinlich auch nicht manuell bef├╝llen, sondern aus z.B. eine CSV Datei auslesen. Wenn man das geschickt l├Âst, kann man vlt die manuelle Eingabe und die automatisierte Version dann mit dem selben Code abarbeiten.

    Vlt ist deine L├Âsung eine Variante, die die konkrete Aufgabenstellung von @adii950 l├Âst, aber der Ansatz als solcher ist f├╝r das Gesamtproblem meiner Meinung nach nicht unbedingt besser geeignet (wenn man von so Kleinigkeiten wie Compilierbarkeit und Ausf├╝hrbarkeit mal absieht ­čśë )



  • @Schlangenmensch
    Wenn ich mir den Code von adii950`s erstem Beitrag und vor allem die Zeilen 73-84 anschaue, ist eine L├Âsung des von Dir deklariertem Gesamtproblems wohl eher zweitrangig .

    Warum ├╝bernimmt eine Funktion die ausgabe hei├čt, eine Referenz und d├╝rfte somit ├änderungen an der Datenstruktur vornehmen.

    Weil ich heute zu geizig f├╝r const bin.

    Also, warum bekommt eine Funktion die "neu" hei├čt, eine Referenz auf einen Vektor ├╝bergeben und gibt nichts zur├╝ck?

    Gef├Ąllt Dir "neues_buch_eingeben" besser?

    Warum macht eine Funktion die neu hei├čt Ausgaben auf std::cout

    Entweder bist Du bl├Âd oder ich.



  • @yxcvbn sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    @Schlangenmensch
    Wenn ich mir den Code von adii950`s erstem Beitrag und vor allem die Zeilen 73-84 anschaue, ist eine L├Âsung des von Dir deklariertem Gesamtproblems wohl eher zweitrangig .

    Es mag sein, dass @adii950 noch C++ Grundlagen fehlen, aber ich bin der Meinung, dass man C++ Nachwuchs auch direkt zeigen muss, wie man Software ordentlich designed. Viele Probleme mit denen sich Anf├Ąnger sonst n├Ąmlich irgendwann rum schlagen, treten dann gar nicht auf.

    @yxcvbn sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    Weil ich heute zu geizig f├╝r const bin.

    Sollte man, gerade in einem ├Âffentlichen Beitrag, nicht sein. Das sehen nur Leute, die das nicht beurteilen k├Ânnen und das nach machen.
    Ich habe ein Projekt geerbt, in dem 20 Jahre keinerlei const verwendet wurde. Das macht keinen Spa├č zu debuggen.

    @yxcvbn sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    Gef├Ąllt Dir "neues_buch_eingeben" besser?

    Auch dann w├╝rde es mir besser gefallen, wenn die Funktion ein Buch zur├╝ck gibt und nicht auf einer Vektor Referenz hantiert.

    @yxcvbn sagte in Muss die Werte von dem Buch einlesen aber bekomme es nicht richtig hin mit dem Vector ­čśů:

    Entweder bist Du bl├Âd oder ich.

    Kann schon sein, dass ich bl├Âd bin. Aber ich w├╝rde gerne auch neue Buchobjekte erstellen k├Ânnen, wenn ich kein Terminal zur Verf├╝gung habe. ├ťberhaupt, erwarte ich von einer Funktion die ein neues Buchobjekt erstellen sollte, eigentlich keine Ausgabe irgendwo.

    F├╝r mich sind std::cin und std::cout auch globale Objekte, die man nur sp├Ąrlich einsetzen sollte, da man im Zweifel deren Zustand nicht kennt und die es schwer machen Unittests zu schreiben. Ich w├╝rde zumindest Stream Objekt Referenzen in die Funktion geben die dann bei bedarf mit std::cin und std::cout aufgerufen werden k├Ânnen (├Ąhnlich wie std::getline da macht).

    Als alternative

    buch neu(std::istream& in, std::ostream& out)
    {
      buch b;
      out << "Bitte titel eingeben:\n";
      getline(in, b.titel);
      out << "Bitte autor eingeben:\n";
      getline(in, b.autor);
      return b;
    }
    

    Finde ich auch noch nicht sch├Ân, ist immer noch Eingabe und Ausgabe in einer Funktion, aber damit lie├čen sich zumindest Unit Test schreiben.

    User Eingaben ├╝ber die Konsole zu verarbeiten ist irgendwie nie sch├Ân und finde ich daher auch immer etwas unpassend, wenn es darum geht jemandem C++ beizubringen. Auf der anderen Seite sieht man da recht schnell Ergebnisse.

    Besser w├Ąre es wahrscheinlich sich ein Eingabe Format zu ├╝berlegen, wie
    <Buch Titel>;<Autor>; <Jahr>...
    Das ganze in einer Zeile einzulesen und dann zu parsen. Dann hat man aber das Problem, was macht man wenn ein ";" im Titel vorkommt... wieder extra F├Ąlle, die den Code umfangreicher machen. Daf├╝r kann man das dann auch verwenden um aus einer CSV direkt eine ganze Liste B├╝cher einzulesen.


Log in to reply