Problem beim beenden einer cin Eingabe


  • Mod

    cin_clear schrieb:

    du hast noch was im Stream stehen was mit cin eingelesen wird, drum läuft das druch.

    bau mal

    std::cin.ignore(256, '\n')
    

    mit ein...

    Nein.



  • Vielen Dank SeppJ das hat geholfen!
    Aber nur wenn ich das erste cin mit strg + Z beende!
    Wie erreiche ich, dass durch die Eingabe von zb "e" die Eingabe beendet wird?


  • Mod

    seppinobis schrieb:

    Vielen Dank SeppJ das hat geholfen!
    Aber nur wenn ich das erste cin mit strg + Z beende!
    Wie erreiche ich, dass durch die Eingabe von zb "e" die Eingabe beendet wird?

    In dem Fall ist das 'e' noch im Stream, da es nicht als Zahl gelesen werden konnte. Wenn du beim nächsten Mal wieder versuchst, eine Zahl zu lesen, wird das entsprechend wieder scheitern.

    Dies ist, wo solche Dinge wie das ignore, das cin_clear gezeigt hat, ins Spiel kommen. Damit kannst du das 'e' aus dem Stream entfernen. Ein einfaches ignore überspringt ein Zeichen. Ein ignore mit einer Zahl als Argument, überspringt diese Anzahl Zeichen. Ein ignore mit einer Zahl und einem Buchstaben als Argument (wie von cin_clear gezeigt) überspringt bis zu dieser Anzahl Zeichen oder bis das angegebene Zeichen gefunden wurde (welches dann auch entfernt wird). Es gibt noch den Sonderwert std::numeric_limits<std::streamsize>::max() (benötigt den Header "limits"), den man für die Anzahl der Zeichen angeben kann, der dann so viel wie "unendlich" bedeutet.

    Da ignore auch eine Art von Leseaktion ist, muss vor dem ignore natürlich erst noch ein clear erfolgen, sonst schlägt das ignore fehl.

    Bevor du aber wild Zeichen überspringst, solltest du sicher sein, dass dies auch die richtige Art der Fehlerbereinigung ist. Wenn in deinem Beispiel der Nutzer CTRL+Z gedrückt hat, dann würde ein Überspringen von Zeichen dazu führen, dass das erste Zeichen der nächsten (gewünschten!) Eingabe übersprungen würde! Denn CTRL+Z ist kein echtes Zeichen, das jemals im Eingabestrom landet. Du müsstest als unterscheiden zwischen dem Fehlerzustand eof (ausgelöst durch das CTRL+Z) und dem Fehlerzustand fail ohne eof (ausgelöst, wenn etwas nicht korrekt verarbeitet werden konnte, z.B. weil Buchstaben standen, wo Ziffern erwartet wurden). Den Fehlerstatus eines Streams kannst du mit diversen Memberfunktionen des Streams auslesen, guck z.B. hier unter "State flag functions".

    Du merkst schon, das wird kompliziert, wenn man es wirklich konsequent durchziehen möchte. Ich würde da an deiner Stelle nicht viel Zeit drauf verschwenden. Du bist sicherlich der einzige Nutzer deiner Testprogramme und kannst davon ausgehen, dass der Benutzer seine Eingaben korrekt durchführt. Und falls du dich selber mal vertippst ist es auch nicht schlimm, startest du dein Programm eben noch einmal. Die Streams sind nicht wirklich auf Nutzerinteraktion ausgelegt sondern sind wirklich nur das ganz minimale Modell einer Datenquelle. Für richtige Nutzerinteraktion würdest du ein richtiges GUI-Framework nehmen; die sind viel besser auf die Behandlung solcher Dinge ausgelegt.



  • Danke für deine Ausfühliche Erklärung! Wie du sagst verschwende ich darauf jetzt erstmal keine Energie! Vielen Dank dir!



  • Hab noch eine zweites Problem jetzt! Ich häng das einfach mal hier an um kein neues Thema aufmachen zu müssen!

    #include "std_lib_facilities.h"
    
    class Name_value {
    public:
        string name;
        int alter;
        Name_value(string na, int alt)
           :name(na), alter(alt){}
    
    };
    
    int main(){
    
    vector<Name_value> paar;
    
    string n;
    int a;
    
    while (cin >> n >> a){
    
        paar.push_back(n, a);
    
    }
    }
    

    Ist immernoch nach dem Stroustrup Buch! Diesmal will ich Eingaben wie: "Sebastian 12 Adrain 30 Emma 20 ..." in einen vetor bestehend aus Token der Klasse Name_value eingeben. Funzt aber so wie oben nicht! Kann ich das nicht direkt mit pushback in die Token lesen?

    Liebe Grüße



  • paar.push_back(Name_value(n, a));
    


  • Und wie kann ich diese Token in einer Liste dann wieder über cout ausgeben?



  • Danke hat sich erledigt!

    for(int i = 0; i < paar.size(); ++i)
    cout << paar[i].name << " " << paar[i].alter << endl;
    

  • Mod

    Ein wenig hübscher geht es durchaus

    for (auto& a : paar)
        cout << a.name << ' ' << a.alter << '\n';
    

    (Das endl war praktisch überflüssig.)



  • Arcoth schrieb:

    Ein wenig hübscher geht es durchaus

    for (auto& a : paar)
        cout << a.name << ' ' << a.alter << '\n';
    

    (Das endl war praktisch überflüssig.)

    Warum nicht

    const auto&
    

    ? Nicht kritisch, aber grundsätzlich


Anmelden zum Antworten