Umgang mit falscher Datentypeingabe

Lesezeit: 5 Minuten

Umgang mit falscher Datentypeingabe
Zik

Wie gehen Sie in C++ mit falschen Eingaben um? Wenn das Programm beispielsweise nach einer Ganzzahl fragt, wenn Sie ein Zeichen eingeben, sollte es in der Lage sein, etwas zu tun und dann die Eingabe zu wiederholen, aber die Schleife wird unendlich, wenn Sie ein Zeichen eingeben, wenn eine Ganzzahl benötigt wird, und umgekehrt.

Umgang mit falscher Datentypeingabe
Chris

Der Grund, warum das Programm in eine Endlosschleife geht, ist, weil std::cinDas Flag für schlechte Eingabe von wird gesetzt, weil die Eingabe fehlschlägt. Das, was zu tun ist, ist, dieses Flag zu löschen und die fehlerhafte Eingabe aus dem Eingabepuffer zu verwerfen.

//executes loop if the input fails (e.g., no characters were read)
while (std::cout << "Enter a number" && !(std::cin >> num)) {
    std::cin.clear(); //clear bad input flag
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input
    std::cout << "Invalid input; please re-enter.\n";
}

Sehen die C++-FAQ für dieses und andere Beispiele, einschließlich dem Hinzufügen eines Minimums und/oder Maximums in die Bedingung.

Eine andere Möglichkeit wäre, die Eingabe als String zu erhalten und sie mit in eine Ganzzahl umzuwandeln std::stoi oder eine andere Methode, mit der die Konvertierung überprüft werden kann.

  • Ich habe einige Nachforschungen angestellt, bevor ich hier frage. Ich habe gesehen, dass sie cin.ignore(1000, ‘\n’); was macht das? Auch !(cin >> num) gibt einen booleschen Wert zurück? das wusste ich nicht

    – Zik

    27. April 2012 um 11:42 Uhr

  • @Marvin, cin.ignore (1000, '\n') ignoriert/verwirft Zeichen im Eingabepuffer, bis entweder 1000 verworfen wurden oder ein Zeilenumbruch aufgetreten ist, je nachdem, was zuerst eintritt. Es ist eine gute Möglichkeit, eine Linie loszuwerden. Sie werden im Parashift-Beispiel sehen, dass sie die maximale Größe eines Streams anstelle von 1000 verwenden, um eine Zeile mit maximaler Länge zu berücksichtigen. ich benutze cin.sync() weil ich dabei mit dem Benutzer auf Augenhöhe sein möchte (noch nicht die nächste Zeile lesen), also verwerfe ich alles. Endlich, cin hat ein operator void *also kann es nicht in einen booleschen Wert konvertiert werden.

    – Chris

    27. April 2012 um 11:48 Uhr

  • @Marvin, cin >> num schlägt fehl, wenn ein Benutzer ‘a’ eingibt, obwohl ein int erwartet wurde. Es stellt einen Konvertierungsoperator bereit, mit dem es implizit in a konvertiert werden kann void *. Wenn cin in einem schlechten Zustand ist, wird es zurückkommen NULL. Wenn nicht, wird das Objekt zurückgegeben. Dies kann dann genommen und in Bool konvertiert werden: wahr, wenn nicht NULL, falsch, wenn NULL. Die Schleife kann dies dann verwenden, um den benötigten booleschen Ausdruck auszuwerten.

    – Chris

    27. April 2012 um 12:15 Uhr


  • @ VaisakMohan, das wäre auch in Ordnung; es ist eine Möglichkeit, den letzten Absatz zu machen. Beachten Sie jedoch, ob Sie mehrere Eingaben in einer Zeile zählen möchten. Es wäre eine Schande, wenn Sie eine Zeile gültiger Eingaben lesen, den ersten Teil davon konvertieren und die anderen wegwerfen würden. getline funktioniert am besten für tatsächliche zeilenbasierte Eingaben anstelle von Token-basierten. Sie müssen auch auf Leerzeichen achten, die bei Ihrer Konvertierung anders behandelt werden könnten. Darüber hinaus bedeutet das zeilenweise Lesen, dass Sie die Konvertierung durchführen müssen und Fehlerprüfung (abzüglich des Verwerfens fehlerhafter Eingaben aus dem Stream) anstelle von nur letzterem.

    – Chris

    4. November 2020 um 22:45 Uhr

  • Außerdem mit getline, müssen Sie darauf achten, keinen verirrten Zeilenumbruch im Stream zu hinterlassen, bevor Sie ihn verwenden. Bei Verwendung getlinewird im Allgemeinen empfohlen, All-in zu gehen, anstatt zu versuchen, es mit tokenbasiertem Input zu mischen und abzugleichen.

    – Chris

    4. November 2020 um 22:46 Uhr

1646923211 305 Umgang mit falscher Datentypeingabe
AWolfAtTheDoor

Die am besten bewertete Antwort deckt die Lösung wirklich gut ab.

Zusätzlich zu dieser Antwort kann dies helfen, sich ein wenig besser vorzustellen, was vor sich geht:

int main()

    int input = 1;//set to 1 for illustrative purposes
    bool cinState = false;
    string test = "\0";
    while(input != -1){//enter -1 to exit
        cout << "Please input (a) character(s): ";//input a character here as a test
        cin >> input; //attempting to input a character to an int variable will cause cin to fail
        cout << "input: " << input << endl;//input has changed from 1 to 0
        cinState = cin;//cin is in bad state, returns false
        cout << "cinState: " << cinState << endl;
        cin.clear();//bad state flag cleared
        cinState = cin;//cin now returns true and will input to a variable
        cout << "cinState: " << cinState << endl;
        cout << "Please enter character(s): ";
        cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer.
        cout << "test: " << test << endl;
    }
    return 0;    
}

Das Ausgeben des Textes im Puffer in eine Variable ist nicht besonders nützlich, aber es hilft zu veranschaulichen, warum cin.ignore() ist notwendig.

Ich habe auch die Änderung an der Eingabevariablen notiert, denn wenn Sie eine Eingabevariable in Ihrer Bedingung für a verwenden while Schleife oder einer switch-Anweisung kann es in einen Deadlock geraten, oder es kann eine Bedingung erfüllen, die Sie nicht erwartet haben, was das Debuggen verwirrender machen kann.

Testen Sie die Eingabe, um zu sehen, ob sie den Erwartungen Ihres Programms entspricht oder nicht. Wenn dies nicht der Fall ist, machen Sie den Benutzer darauf aufmerksam, dass die von ihm bereitgestellte Eingabe nicht akzeptabel ist.

Sie können es durch den ASCII-Wert überprüfen, ob der ASCII-Wert zwischen 65 bis 90 oder 97 bis 122 liegt, was ein Zeichen wäre.

988230cookie-checkUmgang mit falscher Datentypeingabe

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy