Konsolenfensterschließen verhindern: warum cin clear und co
-
Nein musst du nicht!
das cin.clear nutzt du um Fehlerstatuse zu löschen und aus Sicherheit das nichts mehr im Eingabebuffer ist.
std::cin.ignore(std::cin.rdbuf()->in_avail());
und dann musst du die im Eingabebuffer die befindlichen Zeichen löschen.
Du kannst es zum Beispiel bei Fehlereingaben nutzen (Ein Integer wert wird verlangt und ein String wird eingetippt) und am ende um die Konsole nicht zu schließen
Verstanden?
-
Nein, tut mir leid ich häng da grad ein bisschen:
man braucht den Eingabepuffer NICHT mitten im Programm zu löschen
int main { int a; cin>>a; string b; cin>>b; cout<<a<<b; }(nur ein sehr dummes beispiel) Dieses Programm kann keine Probleme wegen dem Eingabepuffer haben.
wenn ich hingegen die das Konsolenfenster geoeffnet lassen will am Programmende muss ich den Eingabepuffer löschen.
{ int a; cin>>a; cout<<a; string b; cin>>b; }Das Konsolenfenster könnte trotzdem schließen, weil da noch etwas im Eingabepuffer steht.
Das ist zumindest so, wie ich dich verstanden hab:
- Da die Eingabe gepuffert ist, kann es passieren, dass Daten aus dem Puffer als Eingabe gewertet werden und sich das Programm daraufhin trotzdem sofort schließt
Heißt das also, dass ich eigentlich vor jedem cin
std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail());schreiben müsste, weil es sonst zu ner Fehleingabe kommen könnte?
Nein musst du nicht!
Irgendwie komm ich da net mit
-
#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)