Eingabe überprüfen klappt nicht wie geplant ?-)



  • hmm... bei mir funktionierts leider nicht ganz wie geplant... 😕



  • du nutzt doch g++? da hat hume sikkins doch mal gesagt das man da noch cin.sync() brauch.



  • Blue-Tiger schrieb:

    Wo hab ich den Fehler gemacht?

    cin.ignore(cin.rdbuf()->in_avail()); funktioniert nicht portabel, da in_avail() auf vielen Implementationen immer 0 zurückliefert.
    Versuch's mal so:

    while ((cout << "where would you like to place the next coin: ")  && !(cin >> chosenSlot))
    {
        cin.clear();
        while (cin.get() != '\n'); 
        cout << "\n!!! sorry, but that's not a valid slot! !!!\n\n\n";
    }
    


  • hmm.... im VC7 kompiliert das Ganze und funktioniert auch so, wie's soll, im GCC 3.3.1 jedoch nicht.... kennt jemand Rat bzw. weiss, woran das liegen koennte?



  • HumeSikkins schrieb:

    Blue-Tiger schrieb:

    Wo hab ich den Fehler gemacht?

    cin.ignore(cin.rdbuf()->in_avail()); funktioniert nicht portabel, da in_avail() auf vielen Implementationen immer 0 zurückliefert.
    Versuch's mal so:

    while ((cout << "where would you like to place the next coin: ")  && !(cin >> chosenSlot))
    {
        cin.clear();
        while (cin.get() != '\n'); 
        cout << "\n!!! sorry, but that's not a valid slot! !!!\n\n\n";
    }
    

    ich dachte, in_avail() gibt zurueck wieviel noch im Buffer ist? Wenn dem nicht so ist, was ist dann Sinn & Zweck von in_avail()?

    @falsche antwort:
    mit cin.sync(); am Ende gehts, aber was genau macht cin.sync() eigentlich?



  • Ich würde nen gebufferten Input machen - eine Zeile in einen String einlesen und den gesondert behandeln. Etwa so:

    #include <iostream>
    #include <sstream>
    #include <string>
    
    using namespace std;
    
    int main() {
      int x;
      bool read_success = false;
    
      do {
        string line;
        stringstream sstr;
    
        cout << "Bitte geben Sie eine Zahl ein: " << flush;
        getline(cin, line);
    
        sstr.str(line);
        read_success = sstr >> x;
      } while(!read_success);
    
      cout << "Sie haben " << x << " eingegeben." << endl;
    }
    


  • Blue-Tiger schrieb:

    ich dachte, in_avail() gibt zurueck wieviel noch im Buffer ist?

    in_avail liefert die Zeichen die noch im Lesepuffer stehen (also egptr() - gptr()) oder aber, falls hier keine Zeichen mehr stehen, einen "Schätzung" wieviele Zeichen noch im physikalischen Strom sind oder -1, falls keine solche Schätzung möglich ist.
    Eine Implementation die keinen zusätzlichen Lesepuffer für cin verwendet kann also ohne Probleme immer 0 bzw. -1 zurückliefern.

    mit cin.sync(); am Ende gehts, aber was genau macht cin.sync() eigentlich?

    Das Verhalten von sync() ist nur für *Ausgabe*ströme spezifiziert. Stroustrup und einige Iostream-Implementation verbinden mit sync() auf Eingabeströmen aber ein "flush" des Strompuffers.



  • Also nix von wegen portabler C++ Standardbibliothek? 😕

    Blue-Tiger: probier's doch mal mit den guten alten fgets() und sscanf() Funktionen:

    #include <stdio.h>  // bzw. <cstdio> fuer standardkonforme
                        // Entwicklungsumgebungen
    
    // ...
    
    // vorher Text ausgeben "Bitte Zahl eingeben: " oder sowas
    char buf[1024]; int zahl = 0;
    for (;;) {
       if ( fgets( stdin, buf, sizeof(buf) ) == 0 ) break; // Ctrl-D oder Ctrl-Z
       if ( sscanf( buf, "%d", &zahl ) == 1 ) break; // Zahl eingegeben
       // sonst schreibe "Es wurde keine Zahl eingegeben!"
    }
    


  • Power Off schrieb:

    Also nix von wegen portabler C++ Standardbibliothek? 😕

    Doch sicher. Es ist nur nix mit "ich-wünsch-mir-meine-Welt-wie-sie-mir-gefällt". Wenn du auf das vertraust, was dir der Standard garantiert bleibst du portabel. Wenn du auf das vertraust, was du hoffst das passiert (bzw. auf das was dir Implementation X als Komfortfunktionalität anbietet), dann bekommst du natürlich Probleme.

    Btw: Das ist bei den C-Streams auch nicht anders. Wenn du dort z.B. darauf baust, dass fflush(stdin) den Eingabestrom leert (was es in bestimmten Implementationen tut), stehst du letztlich vor einem ähnlichen Problem, da der C-Standard dies nicht garantiert. Vielmehr sagt er, dass es zu undefiniertem Verhalten führt.



  • Ich hab das selbe Problem wie Blue Tiger, würde mich über sowas wie eine eindeutige Lösung freuen...
    Was ich auch noch super fände, wäre, wenn man dieses Auf-Integer-Überprüfen gleichzeitig mit einer Prüfung, ob der Integer zwischen bestimmten Grenzen, zB zwischen 1 und 10 liegt, verbinden könnte. Geht das möglichst elegant?
    mfG,
    Matthias



  • wie wäre es mit:

    const int MIN=1, MAX=10;
    int chosenSlot;
    
    while( (cout << "where would you like to place the next coin: ") && !(cin >> chosenSlot)
            || (chosenSlot<MIN) || (chosenSlot>MAX) )
    { 
            cin.clear(); 
            cin.ignore(); 
            cout << "\n!!! sorry, but that's not a valid slot! !!!\n\n\n"; 
    }
    

    irgendwie verstehe ich das Problem nicht 😉 :p



  • freshman schrieb:

    cin.ignore();
    [/cpp]

    Damit ignorierst du maximal ein Zeichen. Häufig viel zu wenig.

    Dann doch eher:

    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    

    was dann aber letztlich auch nichts weiter ist als:

    while (cin.get() != '\n');
    

Anmelden zum Antworten