String überprüfen | Abfrage überspringt bei falscher Eingabe



  • Ich hab zwei Probleme, und zwar wie überprüfe ich ob der Spieler "ja" oder "nein" in die Konsole eingeben hat um im dem Fall das Programm wiederholen oder es wird abgebrochen?

    2. Wenn die Abfrage kommt, dass der Nutzer eine Zahl eingeben solle und stattdessen ein Sonderzeichen oder irgendwas anderes als eine Zahl ist dann überspringt er alle Schleifen und geht bis zur letzten und beendet das Programm? Wie kann ich bei jeder Abfrage sicher gehen, dass er nur die eine Auswahl hat - die Zahleneingabe? [Foto-Link am Ende des Beitrags]

    #import <iostream>
    #import <windows.h>
    
    int Zahl1, Zahl2, Ergebnis, Exit;
    char Operation;
    
    int main()
    {
    	system("cls");
    	std::cout << "Syntax: <Zahl1> + | - | * | / | % <Zahl2> = Ergebnis" << std::endl << std::endl;
    	Sleep(2*1000);
    
    	do
    	{
    		std::cout << "Geben Sie die erste Zahl ein: ";
    		std::cin >> Zahl1;
    		std::cout << std::endl;
    		std::cout << "Geben Sie die zweite Zahl ein: ";
    		std::cin >> Zahl2;
    		std::cout << std::endl;
    
    		std::cout << "Geben Sie als nächstes die Rechenoperation ein mit der Sie rechnen wollen: ";
    		std::cin >> Operation;
    		std::cout << std::endl;	
    
    		switch(Operation)
    		{
    			case '+':
    				Ergebnis = Zahl1 + Zahl2;
    				std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
    				std::cout << "Beenden(0), Wiederholen(1): ";
    				std::cin >> Exit;
    				std::cout << std::endl;
    				break;
    			case '-':
    				Ergebnis = Zahl1 - Zahl2;
    				std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
    				std::cout << "Beenden(0), Wiederholen(1): ";
    				std::cin >> Exit;
    				std::cout << std::endl;
    				break;
    			case '*':
    				Ergebnis = Zahl1 * Zahl2;
    				std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
    				std::cout << "Beenden(0), Wiederholen(1): ";
    				std::cin >> Exit;
    				std::cout << std::endl;
    				break;
    			case '/':
    				if(Zahl1 || Zahl2 == 0)
    				{
    					std::cout << ("ERROR! Programm beendet vorzeitig um sich nicht zu schaden!") << std::endl << std::endl;
    					Sleep(1000);
    					return 0;
    				}
    				Ergebnis = Zahl1 / Zahl2;
    				std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
    				std::cout << "Beenden(0), Wiederholen(1): ";
    				std::cin >> Exit;
    				std::cout << std::endl;
    				break;
    			case '%':
    				Ergebnis = Zahl1 % Zahl2;
    				std::cout << "Der Rest ist: " << Ergebnis << std::endl;
    				std::cout << "Beenden(0), Wiederholen(1): ";
    				std::cin >> Exit;
    				std::cout << std::endl;
    				break;
    			default:
    				std::cout << "Falsche eingabe: " << Operation << std::endl;
    				std::cout << "Beenden(0), Wiederholen(1): ";
    				std::cin >> Exit;
    				std::cout << std::endl;
    				break;		
    
    		}
    
    	} while(Exit == 1);
    
    	if(Exit > 1 || Exit < 1)
    	{
    		std::cout << "Beendet..." << std::endl << std::endl;
    	}
    
    	system("PAUSE");
    	return 0;
    }
    

    Foto:
    http://imgur.com/sbC2r7f (ich wusste nicht wie man Fotos einfügt)



  • Wenn etwas anderes eingegeben wird als die Nummer, geht cin in einen Fehlerzustand, aus dem er nicht mehr rauskommt, außer mit clear().

    Den Fehlerzustand kann man mit good() oder bad() überprüfen, dann mit clear() zurücksetzt und am besten mit ignore() all fehlehaften Zeichen entfernen.

    Siehe hier:
    http://www.cplusplus.com/reference/istream/istream/



  • baue Dir eine kleine Funktion, die die Überprüfung durchführt. Das funktioniert auch für beliebige Typen 'T'. Dann vereinfacht sich auch Dein Programm wesentlich:

    #include <iostream>
    #include <string>   // std::char_traits<>
    #include <cassert>
    #include <limits>
    #include <stdexcept>
    
    template< typename T >
    T eingabe( std::istream& in, std::ostream& out, const char* text )
    {
        T x;
        while( out << text, (in >> x).fail() )
        {
            out << "Eingabe war fehlerhaft" << std::endl;
            in.clear(); // Fehlerflag zurück setzen
            if( !in.ignore( std::numeric_limits< std::streamsize >::max(), '\n' ) )
                throw std::runtime_error( "Eingabe Stream ist kaputt" );
        }
        return x;
    }
    
    struct Operation
    {
        char get() const { return operator_; }
    
        friend std::istream& operator>>( std::istream& in, Operation& op )
        {
            char c;
            if( in >> c && std::char_traits< char >::find( "+-*/%", 5, c ) == nullptr )
                in.setstate( std::ios_base::failbit );
            else
                op.operator_ = c;
            return in;
        }
    private:
        char operator_;
    };
    
    int main()
    {
        std::cout << "Syntax: <Zahl1> + | - | * | / | % <Zahl2> = Ergebnis" << std::endl << std::endl;
    
        int Exit = 1;   // ## lokale Variablen verwenden
        int Ergebnis;
        do
        {
            auto Zahl1 = eingabe< int >( std::cin, std::cout, "Geben Sie die erste Zahl ein: " );
            auto Zahl2 = eingabe< int >( std::cin, std::cout, "Geben Sie die zweite Zahl ein: " );
            switch( eingabe< Operation >( std::cin, std::cout, 
                "Geben Sie als nächstes die Rechenoperation ein mit der Sie rechnen wollen: " ).get() )
            {
                case '+':
                    Ergebnis = Zahl1 + Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '-':
                    Ergebnis = Zahl1 - Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '*':
                    Ergebnis = Zahl1 * Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '/':
                    if(/*Zahl1 ||*/ Zahl2 == 0) // ## Abfrage von Zahl1 überflüssig
                    {
                        std::cout << ("ERROR! Programm beendet vorzeitig um sich nicht zu schaden!") << std::endl << std::endl;
                        // Sleep(1000);
                        return 0;
                    }
                    Ergebnis = Zahl1 / Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '%':
                    Ergebnis = Zahl1 % Zahl2;
                    std::cout << "Der Rest ist: " << Ergebnis << std::endl;
                    break;
    
                default:
                    assert( ("sollte gar nicht moeglich sein!", 0) );
                    break;            
            }
    
            Exit = eingabe< int >( std::cin, std::cout, "Beenden(0), Wiederholen(1): " );
        } while(Exit == 1);
    
        std::cout << "Beendet..." << std::endl << std::endl;
        return 0;
    }
    


  • Werner Salomon schrieb:

    baue Dir eine kleine Funktion, die die Überprüfung durchführt. Das funktioniert auch für beliebige Typen 'T'. Dann vereinfacht sich auch Dein Programm wesentlich:

    #include <iostream>
    #include <string>   // std::char_traits<>
    #include <cassert>
    #include <limits>
    #include <stdexcept>
    
    template< typename T >
    T eingabe( std::istream& in, std::ostream& out, const char* text )
    {
        T x;
        while( out << text, (in >> x).fail() )
        {
            out << "Eingabe war fehlerhaft" << std::endl;
            in.clear(); // Fehlerflag zurück setzen
            if( !in.ignore( std::numeric_limits< std::streamsize >::max(), '\n' ) )
                throw std::runtime_error( "Eingabe Stream ist kaputt" );
        }
        return x;
    }
    
    struct Operation
    {
        char get() const { return operator_; }
    
        friend std::istream& operator>>( std::istream& in, Operation& op )
        {
            char c;
            if( in >> c && std::char_traits< char >::find( "+-*/%", 5, c ) == nullptr )
                in.setstate( std::ios_base::failbit );
            else
                op.operator_ = c;
            return in;
        }
    private:
        char operator_;
    };
    
    int main()
    {
        std::cout << "Syntax: <Zahl1> + | - | * | / | % <Zahl2> = Ergebnis" << std::endl << std::endl;
     
        int Exit = 1;   // ## lokale Variablen verwenden
        int Ergebnis;
        do
        {
            auto Zahl1 = eingabe< int >( std::cin, std::cout, "Geben Sie die erste Zahl ein: " );
            auto Zahl2 = eingabe< int >( std::cin, std::cout, "Geben Sie die zweite Zahl ein: " );
            switch( eingabe< Operation >( std::cin, std::cout, 
                "Geben Sie als nächstes die Rechenoperation ein mit der Sie rechnen wollen: " ).get() )
            {
                case '+':
                    Ergebnis = Zahl1 + Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '-':
                    Ergebnis = Zahl1 - Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '*':
                    Ergebnis = Zahl1 * Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '/':
                    if(/*Zahl1 ||*/ Zahl2 == 0) // ## Abfrage von Zahl1 überflüssig
                    {
                        std::cout << ("ERROR! Programm beendet vorzeitig um sich nicht zu schaden!") << std::endl << std::endl;
                        // Sleep(1000);
                        return 0;
                    }
                    Ergebnis = Zahl1 / Zahl2;
                    std::cout << "Das Ergebnis ist: " << Ergebnis << std::endl;
                    break;
                case '%':
                    Ergebnis = Zahl1 % Zahl2;
                    std::cout << "Der Rest ist: " << Ergebnis << std::endl;
                    break;
    
                default:
                    assert( ("sollte gar nicht moeglich sein!", 0) );
                    break;            
            }
    
            Exit = eingabe< int >( std::cin, std::cout, "Beenden(0), Wiederholen(1): " );
        } while(Exit == 1);
       
        std::cout << "Beendet..." << std::endl << std::endl;
        return 0;
    }
    

    er spuckt aus, dass nullptr nicht deklariert ist... gibt es keine einfachere Methode die auch für mich verstehbar sein kann? Trotzdem danke 🙂



  • crazyyzarc schrieb:

    er spuckt aus, dass nullptr nicht deklariert ist...

    Das liegt an Deinem veralteten Compiler. Dann ersetzte doch 'nullptr' durch eine 0



  • ich benutze kein Visual Studio C++ aber Dev-C++ 😃

    Er spuckt nun:
    Error: Zahl1, Zahl2 was not declared in this scope

    hab schon versucht irgendwie es mal darüber zu deklarieren aber ohne Erfolg


Log in to reply