Warum ergibt das eine Endlosschleife?



  • [OT]
    @FreakY<3Cpp
    Du alter freak, sag nicht du gehst morgens vor der Schule noch ins Forum 😃
    [/OT]



  • Kóyaánasqatsi schrieb:

    [OT]
    @FreakY<3Cpp
    Du alter freak, sag nicht du gehst morgens vor der Schule noch ins Forum 😃
    [/OT]

    DU alter freak :p ...
    Naja die verdammten Züge meinen nicht zu fahren. Jetzt muss ich erst mal gleich zur Schule gefahren werden und weil was wichtiges ist, muss ich da auch noch hin. Ansonsten würde ich wieder im Bett liegen und von Sachen träumen, was genau, will ich jetzt nicht weiter erläutern.


  • Mod

    Criseas schrieb:

    Okey aber wenn ich in der While(cin>>variable)

    hab und ich des mit strg+z abbreche.. müsste es doch weiterlaufen bis zu der eingabe wo ich das Programm beenden oder Weiterlaufen müsste... oder seh ich das falsch?

    Haste eigentlich Recht, war gestern ein bisschen spät, als ich geantwortet habe 🙄 . Kannst du mal deinen Operator >> zeigen?



  • Hmm okey schon, ich weiß das ich das mit counter oder einer eindeutigen Bedingungen machen könnte.

    Aber es geht ja auch das die While solange läuft wie man eingaben tätigt.. Jedenfalls steht es so im C++ Primer

    while(cin>>eingabe)
    

    Und das durch ein EOF die While unterbrochen wird.

    Allerdings gerate ich dadurch wie oben geschrieben in eine Dauerschleife.. und ich versteh nicht warum.

    Die Variablen item2-4 kann man vergessen die sind noch nicht deklariert.

    @SeppJ das ist "eingabe"

    Viele Grüße



  • Criseas schrieb:

    @SeppJ das ist "eingabe"

    ???????????????????

    Der Sepp hat dich gebeten den >>Operator für die Klasse Sales_item herzuzeigen.

    Es sieht im Moment so aus, als wurde für die Klasse Sales_item der >>Operator überladen. Um dir helfen zu können müsste man daher wissen, was dort gemacht wird.



  • Achsoo,
    ja sorry bin noch nicht soweit in der Materie, in dem Buch sind die mir Bekannten Operationen von der Klasse das Addieren von Sales_item objekten. Sowie das Vergleichen von 2 ISBNs mittels variable.same_isbn(variable) als Elementfunktion sowie das lesen und schreiben sowie zuweisen mit cin und cout und =.

    Mehr ist mir von der Klasse noch nicht bekannt.
    Wenn ihr mir sagt was ich euch nun genau zeigen soll kann ich das tun. So versteh ich aber nicht was ihr mit Überladen meint.

    Danke euch soweit schonmal^^

    Grüße

    Criseas


  • Mod

    Irgendwo, vermutlich in einer Datei namens sales_item.cpp oder so ähnlich, gibt es sowas in der Art:

    std::ostream& operator<<(std::ostream& lhs, Sales_item const& rhs) // Genaue Syntax und Variablennamen können anders sein
    {
     // Und das was hier steht, müssen wir wissen um dir zu helfen
    }
    


  • Was Sepp wohl meint ist

    istream& operator>>(istream&, Sales_item&);
    

    Also, Eingabe und nicht Ausgabe.


  • Mod

    hmpf schrieb:

    Was Sepp wohl meint ist

    istream& operator>>(istream&, Sales_item&);
    

    Also, Eingabe und nicht Ausgabe.

    Ähh, ja, bin gerade durcheinander gekommen.



  • So ich hoffe ich darf das posten ansonsten sagt mir bescheid dann lösch ich das wieder :).

    /*
     * This file contains code from "C++ Primer, Fourth Edition", by Stanley B.
     * Lippman, Jose Lajoie, and Barbara E. Moo, and is covered under the
     * copyright and warranty notices given in that book:
     * 
     * "Copyright (c) 2005 by Objectwrite, Inc., Jose Lajoie, and Barbara E. Moo."
     * 
     * 
     * "The authors and publisher have taken care in the preparation of this book,
     * but make no expressed or implied warranty of any kind and assume no
     * responsibility for errors or omissions. No liability is assumed for
     * incidental or consequential damages in connection with or arising out of the
     * use of the information or programs contained herein."
     * 
     * Permission is granted for this code to be used for educational purposes in
     * association with the book, given proper citation if and when posted or
     * reproduced.Any commercial use of this code requires the explicit written
     * permission of the publisher, Addison-Wesley Professional, a division of
     * Pearson Education, Inc. Send your request for permission, stating clearly
     * what code you would like to use, and in what specific way, to the following
     * address: 
     * 
     * 	Pearson Education, Inc.
     * 	Rights and Contracts Department
     * 	75 Arlington Street, Suite 300
     * 	Boston, MA 02216
     * 	Fax: (617) 848-7047
    */ 
    
    #ifndef SALESITEM_H
    #define SALESITEM_H
    
    // Definition of Sales_item class and related functions goes here
    
    #include <iostream>
    #include <string>
    
    class Sales_item {
    friend bool operator==(const Sales_item&, const Sales_item&);
    // other members as before
    public:
        // added constructors to initialize from a string or an istream
        Sales_item(const std::string &book):
                  isbn(book), units_sold(0), revenue(0.0) { }
        Sales_item(std::istream &is) { is >> *this; }
        friend std::istream& operator>>(std::istream&, Sales_item&);
        friend std::ostream& operator<<(std::ostream&, const Sales_item&);
    public:
        // operations on Sales_item objects
        // member binary operator: left-hand operand bound to implicit this pointer
        Sales_item& operator+=(const Sales_item&);
        // other members as before
    
    public:
        // operations on Sales_item objects
        double avg_price() const;
        bool same_isbn(const Sales_item &rhs) const
            { return isbn == rhs.isbn; }
        // default constructor needed to initialize members of built-in type
        Sales_item(): units_sold(0), revenue(0.0) { }
    // private members as before
    private:
        std::string isbn;
        unsigned units_sold;
        double revenue;
    
    };
    
    // nonmember binary operator: must declare a parameter for each operand
    Sales_item operator+(const Sales_item&, const Sales_item&);
    
    inline bool 
    operator==(const Sales_item &lhs, const Sales_item &rhs)
    {
        // must be made a friend of Sales_item
        return lhs.units_sold == rhs.units_sold &&
               lhs.revenue == rhs.revenue &&
    	   lhs.same_isbn(rhs);
    }
    
    inline bool 
    operator!=(const Sales_item &lhs, const Sales_item &rhs)
    {
        return !(lhs == rhs); // != defined in terms of operator==
    }
    
    using std::istream; using std::ostream;
    
    // assumes that both objects refer to the same isbn
    inline
    Sales_item& Sales_item::operator+=(const Sales_item& rhs) 
    {
        units_sold += rhs.units_sold; 
        revenue += rhs.revenue; 
        return *this;
    }
    
    // assumes that both objects refer to the same isbn
    inline
    Sales_item 
    operator+(const Sales_item& lhs, const Sales_item& rhs) 
    {
        Sales_item ret(lhs);  // copy lhs into a local object that we'll return
        ret += rhs;           // add in the contents of rhs 
        return ret;           // return ret by value
    }
    
    inline
    istream& 
    operator>>(istream& in, Sales_item& s)
    {
        double price;
        in >> s.isbn >> s.units_sold >> price;
        // check that the inputs succeeded
        if (in)
            s.revenue = s.units_sold * price;
        else 
            s = Sales_item();  // input failed: reset object to default state
        return in;
    }
    
    inline
    ostream& 
    operator<<(ostream& out, const Sales_item& s)
    {
        out << s.isbn << "\t" << s.units_sold << "\t" 
            << s.revenue << "\t" <<  s.avg_price();
        return out;
    }
    
    inline
    double Sales_item::avg_price() const
    {
        if (units_sold) 
            return revenue/units_sold; 
        else 
            return 0;
    }
    
    #endif
    

  • Mod

    Nie im Leben gibt das eine Endlosschleife. Ist das ganz sicher der richtige Code? Mit allen Klammern exakt so wie hier geschrieben?

    while(count==1)
        {
          cout<<"Geben sie ihre ISBN ein!"<<endl;
          cin>>item1;
          cout<<"next"<<endl;
          while(cin>>eingabe)
          {
            if(eingabe.same_isbn(item1))
            {
              item1 = item1 + eingabe;
              cout<<"next"<<endl;
              count++;
            } else {
              cout<<"Ungültige eingabe!"<<endl;
            }
          }
          cout<<count<<" Transaktionen: "<<item1<<endl;
          cout<<"1. Weiter | 2. Abbruch"<<endl;
          cin>>count;
          if(count!=1) {
                     return 0;
                     }
          return 0;
        }
    

    Wie sieht denn die Ausgabe aus?



  • SeppJ schrieb:

    Nie im Leben gibt das eine Endlosschleife. ...

    Sehe ich auch so. Im Gegenteil durch das return 0 innerhalb der while (count==1) Schleife ist man sogar früher als geplant aus dem Programm heraus.

    Der hier präsentierte Quelltext stimmt wohl nicht mit dem überein, was der Fragesteller daheim ausführt.



  • Die Ausgabe sieht wie folgt aus:

    F:\Salesitem2.exe
    Geben sie ihre ISBN ein!
    0-201-78345-x 5 50.00
    next
    0-201-78345-x 3 25.00
    next
    0-202-78343-x 2 20.00
    Ung³ltige eingabe!
    0-201-78345-x 3 25.00
    next
    ^Z
    3 Transaktionen: 0-201-78345-x 11 400 36.3636
    1. Weiter | 2. Abbruch

    F:\

    wie mann nach
    1. Weiter | 2. Abbruch

    sehen kann konnte ich nixmehr eingeben!

    Aber durch eine Änderung weiter oben nehmlich

    cout<<"Geben sie ihre ISBN ein!"<<endl;
          cin>>item1;
          cout<<"next"<<endl;
          while(cin>>eingabe)
    

    geht es auch nichtmehr in eine Dauerschleife und ich weiß warum!! AHA

    Die Frage ist nun geklärt. Aber warum Funktioniert es nicht so wie gewünscht? Also warum kann ich vor der IF den Eingabestream nicht benutzen?


  • Mod

    😡 Dann war die frage die ganze Zeit, warum das keine Endlosschleife ergibt? Na vielen Dank, das hätten wir dir auch sofort beantworten können. 😡

    Criseas schrieb:

    Die Frage ist nun geklärt. Aber warum Funktioniert es nicht so wie gewünscht?

    Um es mal direkt zu sagen: Weil dein Code ein totales Schlamassel ist. FreakY<3Cpp hat schon ein paar passende Bemerkungen gemacht. Dein Einsatz der Kontrollstrukturen ist total wirr und sinnlos. Schmeiss den ganzen Code weg. Mach dir erstmal Gedanken, wie dein Programm ablaufen soll. Das malst du dir dann auf einem Blatt Papier als Ablaufplan hin. Und diesen Plan übersetzt du dann in C++ Kontrollstrukturen. Und dann wird das auch funktionieren.



  • Auch wenn ich jetzt das Bedürfnis verspüre eine Made zu zerquetschen, würde ich nicht so weit gehen wie der Sepp.

    Die Schleife while(count==1) bricht auf jeden Fall ab, weil du das zweite return 0 innerhalb dieser Schleife positioniert hast und nicht kurz vor Ende der main() wo es vermutlich hin soll.

    Und das cin kannst du vor dem if nicht so einfach verwenden, weil durch den Abbruch mit STRG-Z das Objekt cin noch immer in einem Fehlerzustand ist. Du müsstest also den Puffer leeren und den Fehlerzustand beseitigen. Dann kannst du damit die Variable count einlesen.

    Ansonsten ist dein Programm ganz OK und wird wohl auch tun, was du geplant hast.



  • Nein, SeppJ hat Recht, der Code ist Müll und macht überhaupt keinen Sinn.



  • FreakY<3Cpp schrieb:

    Nein, SeppJ hat Recht, der Code ist Müll und macht überhaupt keinen Sinn.

    Dem kann ich nicht zustimmen.

    Die Kontrollstrukturen sind absolut OK und hätten ohne die allgemeine Vewirrung/Schwierigkeit mit cin wunderbar gearbeitet.

    Als nächstes wird der Fragesteller wohl merken, dass er mit item1, item2, item3 nicht ganz das erreicht was er plant und sich z.B. mit Arrays beschäftigen.

    Programmiertechnisch ist das also schon OK und absolut im Rahmen des Weges den ein Programmieranfänger nun mal gehen muss.

    Ich denke gerade DU kannst dich gut in diese Lage hineinversetzen.



  • Danke euch leute^^,

    Etwas zu meiner Verteidigung.

    Anfangs war es wirklich so das eine Dauerschleife kam. Allerdings habe ich den Fehler irgendwann gefunden, und später ja die andere Version mit dem cin in der While Schleife gepostet. Da hat ich das Problem vergessen neu zu Definieren.

    Danke dir Hmpf für die Verteidigung :). Das Programm tut eigtl schon was es soll nur Hmpf hat mir gerade den Fehler genannt den ich hatte.

    Der Puffer muss geleert werden... das kann ich mit cout tun soweit ich weiß!? Allerdings möcht ich das ja ungern ausgeben, gibt es noch eine andere möglichkeit den Puffer zu leeren sodas ich cin wieder verwenden kann?

    Wie muss ich das mit dem Puffer eigtl genau verstehen, das wurde im Buch noch nicht erläutert, denn ich kann die ganze Zeit Daten eingeben ohne das soetwas passiert?

    Danke schonmal^^

    Grüße
    Criseas



  • Was redest du immer von Kontrollstrukturen? Ich red garnicht von der Klasse, sondern von der main, die Logik fehlt dort doch total.



  • FreakY<3Cpp schrieb:

    Was redest du immer von Kontrollstrukturen? Ich red garnicht von der Klasse, sondern von der main, die Logik fehlt dort doch total.

    Nachdem du sagst der Sepp hat Recht beziehe ich mich auf die Aussage vom Sepp.

    Die Logik ist doch ersichtlich. Eine Schleife liest das ISBN-Zeug ein und die andere wertet aus und fragt dich ob du es nochmal machen willst, oder abbrechen willst.

    Wo ist das Problem?

    Der Umgang mit der Klasse ist noch etwas seltsam (also die If-Bedingungen in der inneren Schleife) und ein paar Schönheitsfehler sind noch dabei (z.B. würde ich keinen Sales_item-Wert vor der inneren Schleife einlesen lassen), aber sonst ist der gute Criseas doch auf dem richtigen Weg.

    @Criseas
    Mit cout geht das nicht. Das Problem ist der Eingabepuffer. Wenn du etwas eingibst liest cin das aus dem Eingabepuffer und verschiebt es in die Variable.

    Hast du etwas eingegeben, das nicht in die Variable passt (z.B. einen Buchstaben wo eine Zahl verlangt wird, oder zwei Zahlen wo nur eine gebraucht wird), bleibt der nicht zu gebrauchende Teil im Eingabepuffer. Beim nächsten cin Befehl ist also eventuell die Eingabe des Vorhergehenden noch im Eingabepuffer.

    Hast du z.B. einen Buchstaben eingegeben wo eine Zahl erwartet wird, wird das cin-Objekt sogar in einen Fehlerzustand gesetzt und kann vorerst nicht mehr zur Eingabe verwendet werden. Dasselbe gilt für die Eingabe von EOF.

    Du musst also den Eingabepuffer leeren und den Fehlerzustand beseitigen. Vielleicht ist es sogar sinnvoll das vor jeder Eingabe zu tun. Allerdings können dann Daten nicht mehr sozusagen in einem Aufwasch eingegben werden.

    Wie man den Puffer von cin löscht und den Fehlerzustand beseitig sagt dir die Forensuche oder Googgle. Das wurde schon unzählige Male beantwortet.

    Bevor du komplizierte Menüs mit cin und cout aufbaust, solltest du zuerst etwas mit denen experimetnieren, denn die verhalten sich nicht immer so, wie man das erwarten würde.


Anmelden zum Antworten