Falsche Eingabe filtern



  • Hallo ^^

    ich hab ein Problem und wollem ihc nun hier mal erkundigen.

    Ich hab ein kleines Tic Tac Toe Konsolenspiel programmiert funktioniert alles bis jetzt wunderbar nur habe ich ein Problem.

    Um sein Feld zu wählen muss man eben eine Zahl eingeben die als Integer deklariert ist...wenn man jetzt aber ausversehen einen Buchstaben eingibt gibts eine Endlosschleife (bei Zahlen über 9 und unter 0 klappt es mit der falschen Eingabe)

    hier mal der Code wie er jetzt aussieht

    cin >> nSelection;
    
    	if (nSelection == 1 && bBesetzt[0] == false )
    	{
    		cField[0] = cMark;
    		bBesetzt[0] = true;
    	}
    	else if (nSelection == 2 && bBesetzt[1] == false)
    	{
    		cField[1] = cMark;
    		bBesetzt[1] = true;
    	}
    	else if (nSelection == 3 && bBesetzt[2] == false)
    	{
    		cField[2] = cMark;
    		bBesetzt[2] = true;
    	}
            ....usw eben alle 9 Felder 
    	else if (nSelection < 1 || nSelection > 9)
    	{
    		cout << "Falsche Eingabe";
    		bFalse = true;
            }
    
    // der Teil in dem eben die Schleife wiederholt wird ohne den Spieler zu wechseln 
    
    if (nPlayer == 1 && bFalse == false)
    		nPlayer = 2;
    	else if (nPlayer == 2 && bFalse == false)
    		nPlayer = 1;
    
    	bFalse = false;
    

    ich hoffe mir kann mal jmd helfen. ^^ Danke schonmal im vor raus



  • Wenn die Eingabe nicht lesbar ist, bleibt sie im Eingabepuffer stehen und der Stream wird in einen Fehlerstatus versetzt, in dem er nicht vernünftig verwendet werden kann. Beides mußt du erstmal aufräumen:

    if(!cin) // Eingabefehler ist aufgetreten
    {
      cin.clear();                               // Fehlerflags zurücksetzen
      cin.ignore(numeric_limits<size_t>::max()); // Rest der Eingabezeile wegwerfen
    }
    


  • Dankeschön ^^
    Oke also ich hab das ganze jetzt so versucht

    else if (nSelection < 1 || nSelection > 9)
    	{
    		cout << "Falsche Eingabe";
    		bFalse = true;
    		if(!cin)
    		{
    			cin.clear();
    			cin.ignore(numeric_limits<size_t>::max());
    		}
    	}
    

    Aber ich hab so das Gefühl das war nicht richtig weil sich nichts geändert hat.
    Ich muss ja <limits> includen?

    Also ich bin eig noch komplett bei den Grundlagen von C++ ich verusch damit nur die Grundlagen zu festigen aber ich möchte einfach nicht das dass Programm einfach abstürtzt wenn man mal ausversehen einen Buchstaben eintippt.



  • Ich bin mir nicht sicher, was bei einem Fehler in der eingelesenen Variablen steht, aber vermutlich landest du nicht in diesem else-Zweig. Aber das kann dir ein Debugger vermutlich besser erklären als ich.

    PS: Wenn du schon mit Arrays arbeitest, wozu brauchst du dann noch die endlose if-else-Kaskade? Das kann man doch alles in einen Zweig zusammenfassen:

    if(cin && nSelektion>=1 && nSelektion<=9)
    {
      if( !bBesetzt[nSelektion-1] )
      {
        cField[nSelektion-1] = cMark;
        bBesetzt[nSelektion-1] = true;
      }
      else
      {
        cout<<"das Feld ist besetzt"<<endl;
      }
    }
    else
    {
      cout<<"ungültige Eingabe"<<endl;
      if(!cin) // Eingabefehler ist aufgetreten
      {
        cin.clear();                               // Fehlerflags zurücksetzen
        cin.ignore(numeric_limits<size_t>::max()); // Rest der Eingabezeile wegwerfen
      }
    }
    


  • Das setzt aber voraus, dass ein integer-Wert eingelesen und in nSelection gespeichert wurde (Zeile 1 - else if).
    Wenn man allerdings einen Buchstaben eingibt, wird wie bereits erwähnt ein Fehlerflag für cin gesetzt und der Buchstabe verbleibt im stream - kein Wert wird in nSelection gespeichert.
    Demzufolge wird dein else if garnicht durchlaufen.



  • Wow auf die Idee wäre ich niemals im Leben gekommen ^^ Danke dir aber jetzt wird der Spieler gewechselt wenn man eine falsche Zahl eingibt, ich hab das mal so eingebaut.

    if(cin && nSelection>=1 && nSelection<=9)
    {
      if( !bBesetzt[nSelection-1])
      {
        cField[nSelection-1] = cMark;
        bBesetzt[nSelection-1] = true;
      }
      else
      {
        cout<<"das Feld ist besetzt"<<endl;
    	bFalse = true;
      }
    }
    else
    {
      cout<<"ungültige Eingabe"<<endl;
      if(!cin) // Eingabefehler ist aufgetreten
      {
        cin.clear();                               // Fehlerflags zurücksetzen
        cin.ignore(numeric_limits<size_t>::max()); // Rest der Eingabezeile wegwerfen
    	bFalse = true;
      }
    }
    

    Aber ich werd dann morgen erst wieder reinschauen hatte heute nen langen Tag schon seit hlb 4 Nachts auf den Beinen ^^ vielleicht kapier ich das demnächst dann.

    PS: auch das Problem mit der Buchstaben eingabe besteht noch.


Log in to reply