while schleife: Abbruchbedingung gesucht für cin>>mem1



  • Ich habe es neu gebuilded. Das Ergebnis bleibt gleich.
    Ich kann ja mal beschreiben was bei der Ausführung passiert:
    Konsolenfentser öffnet sich und in der ersten Zeile steht:
    Series of numbers for ivec1:
    Dann gebe ich die Zahl ein: 2
    Dann drücke ich Enter
    Dann gebe ich noch eine Zahl ein: 4
    Dann wieder Enter.
    Danach gebe ich einen Buchstaben ein: a
    Danach wieder Enter.
    Mein Konsolenfenster sieht nun so aus:

    Series of numbers for ivec1:
    1
    2
    3
    s
    
    Series of number for ivec2:
    ivec2 is the same like ivec1 at the beginning!
    
    Process returned 0 (0x0)   execution time : 4.382 s
    Press any key to continue.
    

    Ich habe Code::Blocks als IDE und den GNU Compiler der Standartmäßig bei Code::Blocks enthalten ist.



  • Du gibst 2 4 a ein und die Ausgabe ist 1 2 3 s. 😕 Ich würd das Projekt mal löschen, ein neues Projekt erstellen, und den Quellcode von Skym0sh0 dann kopieren.



  • ne sorry das war jetzt mein Fehler... als ich das geschrieben habe, habe ich einfach irgendwelche Zahlen und Buchstaben genommen die mir in den Kopf gekommen sind. War eine komplett neue Datei dann habe ich den neuen Code eingefügt.
    Bei mir funktioniert der Code von Skym0sh0 wirklich nicht. Der Compiler gibt keine Warnung aus und auch keine Fehlermeldung.



  • Hmm, kopier mal deinen aktuellen Quellcode hier rein.



  • #include <iostream>
    #include <vector>
    #include <limits>
    using namespace std;
    
    int main()
    {
        vector<int> ivec1, ivec2;
        cout << "Series of numbers for ivec1:" << endl;
    
        int mem1;
        while(cin >> mem1 && mem1 != 9999) // Notlösung zum abbrechen
            ivec1.push_back(mem1);
    
        cin.clear();
        cin.ignore(numeric_limits<unsigned int>::max(), '\n'); // deine cin's gesetzt
        cout << "\nSeries of number for ivec2:" << endl;
        while(cin >> mem1 && mem1 != 9999) // Notlösung zum abbrechen
            ivec2.push_back(mem1);
    
        int cnt=0;
        if(ivec1.size() <= ivec2.size()){
            for(size_t ix=0; ix != ivec1.size(); ++ix){
                if(ivec1[ix] == ivec2[ix])
                    ++cnt;
            }
            if(cnt == ivec1.size()){
                cout << "ivec1 is the same like ivec2 at the beginning!" << endl;
                return 0;
            }
            else
                cout << "ivec1 and ivec2 are not the same at the beginning!" << endl;
        }
        else if(ivec1.size() > ivec2.size()){
            for(size_t ix=0; ix != ivec2.size(); ++ix){
                if(ivec2[ix] == ivec1[ix])
                    ++cnt;
            }
            if(cnt==ivec2.size()){
                cout << "ivec2 is the same like ivec1 at the beginning!" << endl;
                return 0;
            }
            else
                cout << "ivec1 and ivec2 are not the same at the beginning!" << endl;
        }
    
        return 0;
    }
    

    exakt der gleiche der hier schon einmal gepostet wurde. Im Debug Ordner befindet sich eine ausfürhbare Datei(so wie es sein soll). ich hab es auf release und auf debug compiliert -> kein Erfolg. Ich hatte mal früher ein Buch c++ von a-z (ja ich weiß es ist schlecht) ... ABER in einem Kapitel wurde via while schleife eine Zahl immer wieder neu in eine Variable gespeichert. Diese wurde überschrieben wenn sich die while schleife wiederholte sprich wenn der benutzer eine neue Eingabe machte. Ich weiß dass die while Schleife die Eingabe auf eine Zahl geprüft hat. wenn es keine Zahl war dann wurde eine Fehlermeldung ausgegeben und die Schleife mit break; unterbrochen. Ich kann mich wirklich nur an Bruchstücke entsinne aber da stand meine ich etwas von if(!(cin EOF ) irgendwas. Ich weiß nicht warum das bei mir nicht funktioniert und bei dir schon.



  • Habe mal den Code getestet und hier mein Terminal ergebnis 😉

    $ clang++ test.cpp -o skymosho
    $ ./skymosho 
    Series of numbers for ivec1:
    1
    2
    3
    9999
    
    Series of number for ivec2:
    3
    2
    1
    9999
    ivec1 and ivec2 are not the same at the beginning!
    $ ./skymosho
    Series of numbers for ivec1:
    1
    2
    3
    s
    
    Series of number for ivec2:
    
    3
    2
    1
    9999
    ivec1 and ivec2 are not the same at the beginning!
    

    Ka was du da falsch machst 😉



  • 😞 😞 😞 das kann doch nicht sein.
    Ich habs jetzt auch noch mal unter der Eingabeaufforderung compiliert

    C:\Users\Krex\Desktop\_6.16forum>g++ main.cpp -o main.exe
    
    C:\Users\Krex\Desktop\_6.16forum>main.exe
    Series of numbers for ivec1:
    122
    23
    s
    
    Series of number for ivec2:
    ivec2 is the same like ivec1 at the beginning!
    
    C:\Users\Krex\Desktop\_6.16forum>
    

    Vll muss ich den compiler deinstallieren.. ? Was macht cin eigentlich wenn ich einen Buchstaben eingebe? Versucht es dann nicht das literal in einen int zu konvertieren in dem fall jetzt 97 nach dem ASCII Zeichensatzt. Oder wird die Schleife sofort übersprungen und auch nicht mehr an den Vektor ein neues Element hinzugefügt?


  • Mod

    Kann es sein, dass der Quelltext, den du übersetzt nicht aktuell ist? Das du vielleicht eine andere Kopie davon bearbeitet hast aber versehentlich die alte Version übersetzt? Mit dem Compiler selbst hat das jedenfalls ganz sicher nichts zu tun.
    Änder doch mal was offensichtliches an dem Quelltext, zum Beispiel mach mal den Grammatikfehler "same like" raus (das heißt "same as"!). Die Meldung bei der Ausgabe sollte sich dann entsprechend ändern.

    Was macht cin eigentlich wenn ich einen Buchstaben eingebe? Versucht es dann nicht das literal in einen int zu konvertieren in dem fall jetzt 97 nach dem ASCII Zeichensatzt. Oder wird die Schleife sofort übersprungen und auch nicht mehr an den Vektor ein neues Element hinzugefügt?

    Oh, hier liegen viele Missverständnisse vor:
    -cin ist eine Objektinstanz der Klasse istream, cin selber ist keine Funktion oder gar Schlüsselwort der Sprache. Es ist einfach ein globaler istream, der bei Programmstart an die Standardeingabe gekoppelt wird.
    -istream hat haufenweise Überladungen für den Operator>>. Beispielsweise eine für int. Diese Lesefunktionen versuchen gar nichts mit Gewalt um zu interpretieren, die verstehen bloß die im Standard vorgegebenen Zahlenformate. Ohne Zusatzmanipulatoren also bloß Zahlen im Dezimalformat.
    -Trifft nun diese Lesefunktion für Ganzzahlen auf einen Buchstaben, so ist dies ein Lesefehler. Das Istreamobjekt (also cin) wird in einen Fehlerzustand versetzt und der Buchstabe bleibt im Eingabestrom (genauer: der Fehlerzustand ist "fail". Zu unterscheiden beispielsweise vom Fehlerzustand "eof" der eintritt, wenn der Eingabestrom an seinem Ende* angelangt ist).
    -Solange ein Streamobjekt in einem Fehlerzustand ist, schlagen automatisch alle weiteren Lese- oder Schreiboperationen darauf fehl.
    -Entsprechend wird das Streamobjekt im Fehlerzustand in einem boolschen Kontext (if-Abfrage, oder hier: while-Bedingung) zu "false" ausgewertet.

    *: "Ende" heißt nicht "es sind gerade im Moment keine Zeichen da", sondern "Es sind keine Zeichen da und es werden auch niemals weitere kommen". Beispiele sind das Ende von Dateien (eof = end of file) oder wenn die Standardeingabe über entsprechende Steuerzeichen geschlossen wird (Linux CTRL+D, unter Windows afaik CTRL+Z).



  • Den Grammatikfehler habe ich korrigiert. Im Programm steht nun "same as" anstatt "same like". Der Compiler hat also die richtige Datei compiliert(Ging ja auch garnicht anders, weil ich ein komplett neues Projekt erstellt habe). Der Fehler bleibt trotzdem. Also habe ich Code::Blocks komplett deinstalliert und die aktuelle 12.11 Ming Version installiert. Das Ergebnis bleibt gleich.....
    Dann habe ich mir die Visual c++ 2010 Express Edition gedownloaded und installiert.
    Es hat funktioniert 😮
    Wäre jemand von euch so nett und würde den Quellcode auch auf einem MingW Compiler testen? Vielleicht handelt es sich dort um einen bug der nicht nur bei mir auftritt.
    Sorry außerdem, dass ich nicht so schnell zurückschreiben konnte und vielen Dank schonmal für die Antworten die ich schon von euch bekommen habe 😉


  • Mod

    Ist das oben wirklich absolut 100% exakt und ungekürzt der gleiche Quellcode, den du benutzt hast?

    Keksman schrieb:

    #include <iostream>
    #include <vector>
    #include <limits>
    using namespace std;
    
    int main()
    {
        vector<int> ivec1, ivec2;
        cout << "Series of numbers for ivec1:" << endl;
    
        int mem1;
        while(cin >> mem1 && mem1 != 9999) // Notlösung zum abbrechen
            ivec1.push_back(mem1);
    
        cin.clear();
        cin.ignore(numeric_limits<unsigned int>::max(), '\n'); // deine cin's gesetzt
        cout << "\nSeries of number for ivec2:" << endl;
        while(cin >> mem1 && mem1 != 9999) // Notlösung zum abbrechen
            ivec2.push_back(mem1);
    
        int cnt=0;
        if(ivec1.size() <= ivec2.size()){
            for(size_t ix=0; ix != ivec1.size(); ++ix){
                if(ivec1[ix] == ivec2[ix])
                    ++cnt;
            }
            if(cnt == ivec1.size()){
                cout << "ivec1 is the same like ivec2 at the beginning!" << endl;
                return 0;
            }
            else
                cout << "ivec1 and ivec2 are not the same at the beginning!" << endl;
        }
        else if(ivec1.size() > ivec2.size()){
            for(size_t ix=0; ix != ivec2.size(); ++ix){
                if(ivec2[ix] == ivec1[ix])
                    ++cnt;
            }
            if(cnt==ivec2.size()){
                cout << "ivec2 is the same like ivec1 at the beginning!" << endl;
                return 0;
            }
            else
                cout << "ivec1 and ivec2 are not the same at the beginning!" << endl;
        }
    
        return 0;
    }
    

    Du hast kein in_avail, fflush oder sonstiges eingebaut?

    Ganz, ganz, ganz sicher?

    Wirklich sicher? Hast du auch 3x nachgeguckt? Jeder noch so kleine Unterschied könnte die Ursache sein, weil du vielleicht gar nicht die Tragweite dieses Unterschieds erkennen kannst.

    Denn fflush und in_avail würden nämlich tatsächlich was anderes machen in VS als bei mingw, was so einiges von deinen Beobachtungen erklären würde. Wenn das jedoch wirklich dein Quellcode ist, dann: 😕 ? Eigentlich kann das gar nicht sein.



  • 😮 Er hat recht. Es funktioniert mit dem MinGW (4.6.1) wirklich nicht. Habs eben ausprobiert.

    #include <iostream>
    #include <vector>
    #include <limits>
    using namespace std;
    
    int main()
    {
        vector<int> ivec1, ivec2;
    	cout << "Series of numbers for ivec1:" << endl;
    
        int mem1;
        while(cin >> mem1 && mem1 != 9999);
    
        cin.clear();
        cin.ignore(numeric_limits<unsigned int>::max(), '\n');
    
        cout << "\nSeries of number for ivec2:" << endl;
        while(cin >> mem1 && mem1 != 9999);
    }
    

    Funktioniert nicht.

    So funktioniert es aber:

    #include <iostream>
    #include <vector>
    #include <limits>
    using namespace std;
    
    int main()
    {
        vector<int> ivec1, ivec2;
    	cout << "Series of numbers for ivec1:" << endl;
    
        int mem1;
        while(cin >> mem1 && mem1 != 9999);
    
        cin.clear();
        cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    
        cout << "\nSeries of number for ivec2:" << endl;
        while(cin >> mem1 && mem1 != 9999);
    }
    

    😃 numeric_limits<unsigned int>::max() führt wohl zu einem Überlauf ( ignore will einen signed int haben) und damit zu UB.



  • out schrieb:

    😃 numeric_limits<unsigned int>::max() führt wohl zu einem Überlauf ( ignore will einen signed int haben) und damit zu UB.

    MinGW: sizeof(unsigned int) == 4 Byte
    MinGW: sizeof(std::streamsize) == 4 Byte

    MSVC11: sizeof(unsigned int) == 4 Byte
    MSVC11: sizeof(std::streamsize) == 8 Byte

    ➡ Wie eben angesprochen. ➡ Überlauf. An das hat nun eben auch keiner gedacht. Aber ist alles doch ganz logisch. 💡



  • Danke dir 😉
    Funktioniert jetzt auch bei mir mit Code::Blocks und Visual C++ 2010 express.


  • Mod

    Oh, na klar! Wie konnte ich bloß das unsigned int übersehen, nachdem ich Skym0sh0 schon für das falsche in_avail angefahren habe?

    Skym0sh0, besser aufpassen, was du schreibst 😉 !



  • 😃 war Absicht und alle sind drauf reingefallen 😃

    ~ne wars nicht 😞 *okayface.jpg*~



  • out schrieb:

    numeric_limits<unsigned int>::max() führt wohl zu einem Überlauf ( ignore will einen signed int haben) und damit zu UB.

    Nein, kein UB.

    §4.7/3 schrieb:

    If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.



  • SeppJ schrieb:

    Oh, na klar! Wie konnte ich bloß das unsigned int übersehen, nachdem ich Skym0sh0 schon für das falsche in_avail angefahren habe?

    Wie war das nochmal... ein alter Mann...

    Immer mit der Ruhe, ein alter Mann ist kein D-Zug Wikipedia-Löschadmin.

    Nachtrag: Meine Fresse! Der Thread ist ja eine Peinlichkeit ... bitte keiner den Link bereitstellen.


Anmelden zum Antworten