Konsolenfensterschließen verhindern: warum cin clear und co



  • #include <iostream>
    using namespace std;
    int main()
    {
     int a;
     cin>>a;
     char b[5];
     cin>>b;
     cout<<a<<b;
    }
    

    okay ich werde es dir so gut wie möglich jetzt erklären!
    jetzt tu mal dieses Programm Kompilieren!
    Und sag mir mal was für ein Compiler du benutzt!
    so starte die .exe Anwendung und gebe, da int eine zahl ist, am anfang einen Buchstaben ein also ein Fehler, da ein integer verlangt wird.
    So das programm sollte folgendes ausgeben:
    a
    4314411
    und dann sofort beenden! ohne das du die b eingeben kannst!
    so und dass wollen wir verhindern dafür brauchen wir das cin.clear und das
    std::cin.ignore(std::cin.rdbuf()->in_avail());

    #include <iostream>
    using namespace std;
    int main()
    {
    	int a;			//Integer a
    	cin>>a;	
    	while(true)		//Endlosschleife
    	{
    
    		if (cin.fail()) //falls im Eingabebuffer ein fehler ist wie zum Beipiel ein A
    		{
    			cin.clear();								//Eingabebufferlöschen
    			cin.ignore(std::cin.rdbuf()->in_avail());	//Restzeichenlöschen
    			cout<<"Eingabe falsch! Wiederholen:"<<endl;	
    			cin>>a;										//neue Eingabe
    		}
    		else
    			break;		//Schleifenabruch
    	}
    	char b[2];		
    	cin>>b;
    	while(true)
    	{
    		if (cin.fail()) //falls im Eingabebuffer ein fehler ist
    	{
    			cin.clear();
    			cin.ignore(std::cin.rdbuf()->in_avail());
    			cout<<"Eingabe falsch!";
    			cin>>b
    	}
    		else
    			break;
    	}
    	cout<<a<<b;		//Ausgabe
    }
    

    Hier wenn du im Erstem ein A eingibst gibt er eine Fehler meldung da cin.fail dann ist. Der Fehler wird gelöscht und eine neue Eingabe wird gefordert.
    Ich hoffe mal das dir das weider hilft bei fragen frag einfach



  • Sehr gut beschrieben. Sowas gehört eigentlich mal ins FAQ, oder steht das schon dadrin und ich habs übersehen?



  • Vielen Dank, jetzt hab ichs kapiert! Das heisst also, dass ich tatsaechlich quasi nach jedem cin diese Kontrolle besser machen sollte (ausser man geht von der Fehlerlosigkeit der Benutzer aus... und die ist denke ich aber sehr selten) Es hat mich oben ein bisschen verwirrt, dass ich das bei eingaben mitten im Programm nicht zu machen braeuchte.

    Nur noch eine kurze Frage:

    statt dieser while(true) koennte man da auch einfach:

    while(cin.fail())
    ...
    

    schreiben?



  • am besten noch so

    do
    {
    //cin und so
    } while(!cin);
    


  • auch wieder wahr.

    Danke! !cin und cin..fail() bedeuten das gleiche, ja?



  • Ja, !cin und cin.fail() bedeuten das gleiche.

    Ich habe das Problem, dass der Code den Dying vorgestellt hatte, nicht so funktioniert, wie ich es wollte. Geb cih beispielsweise ein 's' ein, gerät er danach in eine Endlosschleife, mir ist es nicht möglich, eine neue eingabe zu machen...

    Ich hab auch schon mal probiert, das

    cin.ignore(std::cin.rdbuf()->in_avail());
    

    durch ein

    cin.seekg(0L,ios:.end)
    

    zu ersetzen. ( Hab ich aus einem Buch)
    klappt beides nicht



  • Hm kann sein weil ich im code ein fehler hab

    #include <iostream>
    using namespace std;
    int main()
    {
        int a;            //Integer a
        cin>>a;   
        while(true)        //Endlosschleife
        {
    
            if (cin.fail()) //falls im Eingabebuffer ein fehler ist wie zum Beipiel ein A
            {
                cin.clear();                                //Eingabebufferlöschen
                cin.ignore(std::cin.rdbuf()->in_avail());    //Restzeichenlöschen
                cout<<"Eingabe falsch! Wiederholen:"<<endl;   
                cin>>a;                                        //neue Eingabe
            }
            else
                break;        //Schleifenabruch
        }
        char b[2];       
        cin>>b;
        while(true)
        {
            if (cin.fail()) //falls im Eingabebuffer ein fehler ist
        {
                cin.clear();
                cin.ignore(std::cin.rdbuf()->in_avail());
                cout<<"Eingabe falsch!";
                cin>>b; //<<da war der fehler hab das selimikon vergessen
                        //Manche Compiler juckt das nicht und es kommen fehler...
        }
            else
                break;
        }
        cout<<a<<b;        //Ausgabe
    }
    

    Wenn es nicht dann weiß ich auch nicht was dein problem ist...



  • hi, hatte deinen Code mit copy & paste übernommen, klappte aber trotzdem wie gesagt
    nicht. Hab jetzt aber aus nem anderen tut ne Lösung die funktioniert:

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

    statt

    cin.ignore(std::cin.rdbuf()->in_avail());
    

    Verstehe aber immer noch nicht, warum die Variante mit

    cin.ignore(std::cin.rdbuf()->in_avail());
    

    nicht funktioniert. Jemand ne Idee?



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

    solange du das kapierst ist alles gut aber pass auf der leert den Buffer nur bis '\n' 😉 was für ein Compiler?



  • hab dev-c++, weiß leider net, was da für ein compiler hintersteckt...
    Bis '\n' zu löschen sollte aber doch für die misten Eingaben reichen, oder?



  • !cin und cin.fail() sind nicht das gleiche, ersteres ist wahr wenn !cin.good() wahr ist bzw. cin.good() falsch ist und letzteres ist nur wahr wenn das failbit gesetzt ist. Es gibt aber auch noch das badbit und das eofbit.
    Und ich glaub die stream-callbacks können da auch noch mitmischen, bin ich mir aber nicht zu 100% sicher.



  • lolz schrieb:

    !cin und cin.fail() sind nicht das gleiche, ersteres ist wahr wenn !cin.good() wahr ist bzw. cin.good() falsch ist und letzteres ist nur wahr wenn das failbit gesetzt ist. Es gibt aber auch noch das badbit und das eofbit.

    Falsch - schau dir einfach mal ios::operator!() und ios::fail() an, dann siehst du, was sie machen (op! gibt normalerweise fail() zurück und dieses wiederum überprüft das failbit und badbit).

    (außerdem wird auch bei einem EOF das badbit gesetzt)


Anmelden zum Antworten