Eingabe Kontrollieren



  • Hallo
    Das Thema ist eigentlich geklärt.
    Jedoch in meinem Fall komme ich nicht klar

    double zahl;
    
    std::cin>>zahl;
    while(!std::cin){
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
    std::cin>>zahl;
    }
    

    Wenn ich 34.2 eingebe, passt
    wenn ich xzy24 eingebe dann fail() return true
    Wenn ich 24xyz eingebe dann wird 24 gespeichert (while bedingung nicht erfüllt)
    wie kann man im Fall "24.xyz" oder "24xyz" kontrollieren?
    will schließlich das als falsche Eingabe definieren und die Eingabe wiederholen.
    Zahl in string lesen und kontrollieren und schließlich in double umwandeln ist leider nicht erlaubt.

    Vielen Dank 🙂



  • Wenn das nächste Zeichen white space ist, war es ok.



  • Das ist so leider nicht möglich.

    Benutze getline und string(stream).



  • manni66 schrieb:

    Wenn das nächste Zeichen white space ist, war es ok.

    Warum sollte denn "24 XYZ" eine gültige Zahl sein?!

    Man müsste schon schauen, dass entweder der Stream am Ende ist oder ein Zeilenvorschub folgt. Ich finde das immer sehr schwierig richtig zu machen.

    Vielleicht so:

    #include <iostream>
    
    using std::cin;
    
    int main() {
      int i;
      cin >> i;
      if (cin && (cin.eof() || cin.peek() == 10)) {
        std::cout << "Gut.\n";
      } else {
        std::cout << "Nicht gut.\n";
      }
    }
    

    Test:

    ~/test$ echo 4 | ./a.out                            
    Gut.
    ~/test$ echo -n 4 | ./a.out                            
    Gut.
    ~/test$ echo "4 " | ./a.out
    Nicht gut.
    ~/test$ echo -n X | ./a.out
    Nicht gut.
    ~/test$ echo X | ./a.out 
    Nicht gut.
    

    Mir ist das meist zu kompliziert und ich nehme einfach getline 🙂



  • stream-hasser: mach mal so:

    echo -n 'x'|./out
    


  • stream-hasser schrieb:

    manni66 schrieb:

    Wenn das nächste Zeichen white space ist, war es ok.

    Warum sollte denn "24 XYZ" eine gültige Zahl sein?!

    Man müsste schon schauen, dass entweder der Stream am Ende ist oder ein Zeilenvorschub folgt. Ich finde das immer sehr schwierig richtig zu machen.

    Vielleicht so:

    #include <iostream>
    
    using std::cin;
    
    int main() {
      int i;
      cin >> i;
      if (cin && (cin.eof() || cin.peek() == 10)) {
        std::cout << "Gut.\n";
      } else {
        std::cout << "Nicht gut.\n";
      }
    }
    

    Test:

    ~/test$ echo 4 | ./a.out                            
    Gut.
    ~/test$ echo -n 4 | ./a.out                            
    Gut.
    ~/test$ echo "4 " | ./a.out
    Nicht gut.
    ~/test$ echo -n X | ./a.out
    Nicht gut.
    ~/test$ echo X | ./a.out 
    Nicht gut.
    

    Mir ist das meist zu kompliziert und ich nehme einfach getline 🙂

    ja getline ist nicht schlecht
    aber getline muss man wieder mit string arbeiten, leider will ich das direkt in ein double speichern und nicht über Umwege führen.
    kann man eigentlich eingabestrom prüfen

    sowas wie

    prüfe ziffer für ziffer in eingabestrom
    wenn cin.peek()!= 0 bis 9
    dann mit cin.clear() alles im eingabestrom löschen und wieder neu eingeben ?



  • Ein Gast schrieb:

    stream-hasser: mach mal so:

    echo -n 'x'|./out
    

    Da kommt "nicht gut" raus, so wie man sich es denkt, so wie es sein soll.



  • Zeichen für Zeichen auf isdigit() || '.' checken, sonst verwerfen.
    Zeilen mit mehrfachen '.' ebenso verwerfen.
    Da gibt es wahrscheinlich elegantere Methoden, aber ich als alte C-Schleuder würde es so machen.



  • Ein E (oder e) darf aber auch in einem double-Literal vorkommen.



  • DirkB schrieb:

    Ein E (oder e) darf aber auch in einem double-Literal vorkommen.

    Sollte auch kein Ding sein, darauf zu testen. Müsste mir nur die exakte, erlaubte Notation für diese Syntax ansehen.


Anmelden zum Antworten