Buchstabe in Dezimalzahlwert Fehler
-
Hi,
also wenn Du mit cin versuchst in eine Variable einzulesen, deren Typ für den Wert nicht zugänglich ist, dann geht cin "kaputt", d.h. intern erhält es ein Fehler-State. Dieses kannst Du abfragen mit:
if(cin.fail())oder kürzer:
if(!cin)Damit hast Du die Abfrage. Um cin wieder zu reanimieren musst Du das Failbit danach löschen:
cin.clear();Ich bin nicht sicher, ob die alten Zeichen dann noch drinstehen (vermutlich ja), die müsstest Du dann aus dem Stream kicken. Sonst würde eine erneute Eingabe von z.B. 10 nur dazu führen, dass im Stream z.B. "a10" steht, was wieder nicht in einen int geht.
Zum Ignorieren der Zeichen, die noch im Stream sind:
cin.ignore(std::numeric_limits<std::streamsize>::max());Hoffe, das stimmt so und es hat Dir auch noch geholfen.
-
Ok, danke.
Ich habe es jetzt wie folgt eingebaut:
punktX11: cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; cin>>X11; cin.ignore(std::numeric_limits<std::streamsize>::max()); if (!cin) { cin.clear(); cout<<"Bitte wiederholen Sie Ihre Eingabe!"<<endl; cout<<""<<endl; goto punktX11; }Nur jetzt bekomme ich den Fehler, dass numeric_limits kein Element von std ist und dass es aufgrund dessen nun nicht deklariert ist.
-
cin.ignore() brauchst Du nur im Fehlerfall, kann also nach der if-Verzweigung kommen. Ansonsten werden die Zeichen sowieso ausgelesen.

Für numeric_limits:
#include <climits>goto bitte vermeiden, das hat einige Nachteile und kann massiven Spaghetticode erzeugen, am Besten gar nicht erst angewöhnen!
Eine Schleife ist hier das, was Du suchst.
-
Mein Programmcode sieht nun so aus:
Am Anfang des Programm steht auch
using namespace std;,
falls das zu Fehlern führt...punktX11: cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; cin>>X11; if (!cin) { cin.clear(); cout<<"Bitte wiederholen Sie Ihre Eingabe!"<<endl; cout<<""<<endl; goto punktX11; } cin.ignore(numeric_limits<streamsize>::max());Nur leider bekomme ich immer noch Fehler:

1>------ Erstellen gestartet: Projekt: 2 Geraden Schnittpunkt Rechn, Konfiguration: Debug Win32 ------
1>Kompilieren...
1>2 Geraden Schnittpunkt Rechn.cpp
1>c:\users\\documents\visual studio 2008\projects\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn.cpp(32) : error C2065: 'numeric_limits': nichtdeklarierter Bezeichner
1>c:\users\\documents\visual studio 2008\projects\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn.cpp(32) : error C2275: 'std::streamsize': Ungültige Verwendung dieses Typs als Ausdruck
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\iosfwd(25): Siehe Deklaration von 'std::streamsize'
1>c:\users\\documents\visual studio 2008\projects\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn.cpp(32) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)': Erwartet 3 Argumente - 0 unterstützt
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(3390): Siehe Deklaration von 'std::max'
1>c:\users\\documents\visual studio 2008\projects\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn\2 geraden schnittpunkt rechn.cpp(32) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &)': Erwartet 2 Argumente - 0 unterstützt
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(3382): Siehe Deklaration von 'std::max'
1>Das Buildprotokoll wurde unter "file://c:\Users\****\Documents\Visual Studio 2008\Projects\2 Geraden Schnittpunkt Rechn\2 Geraden Schnittpunkt Rechn\Debug\BuildLog.htm" gespeichert.
1>2 Geraden Schnittpunkt Rechn - 4 Fehler, 0 Warnung(en)
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
-
Alle nötigen header eingebunden? So wie du postest ist es nicht komilierbar.
Und das was Eisflamme gesagt hat gilt immer noch:
Eisflamme schrieb:
goto bitte vermeiden
Eine Schleife ist hier das, was Du suchst.while( !( std::cin >> x11 ) ) { }
-
Achso, oh das hab ich ganz übersehn, dass Eisflamme das geschrieben hatte.
Header sind folgende eingebunden:
#include "stdafx.h" #include <conio.h> #include <iostream> #include <climits>Nur Schleifen hatte ich noch nicht im Unterricht.
Da weiß ich jetzt nicht was in die Schleife rein muss.
Und was heißt das, was jetzt hinter while steht?
-
tztztz... goto gelernt aber keine schleifen

du musst
#include <limits>schreiben.
-
operator>> liefert ebenfalls wieder eine Referenz auf cin zurück. Somit bezieht sich ! auch auf cin.
Und while läuft solange wie das im Schleifenkopf true ist. Also solange es hier einen Fehler gibt, wird die Abfrage wiederholt.
Zu den Schleifen findest Du drölfhundert Tutorials, musste einfach googlen.
-
Also jetzt habe ich die limits eingebunden und es kommt auf jeden Fall schonmal kein Fehler mehr

Mein Programmausschnitt sieht jetzt wie folgt aus:
cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; cin>>X11; while( !( std::cin >> X11 ) ) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max()); cout<<"Bitte wiederholen Sie Ihre Eingabe!"<<endl; cout<<""<<endl; }Wenn ich jetzt einen Buchstaben eingebe, kommt gar nichts mehr danach.
So wie ich das jetzt verstehe, löscht er den Speicher und ignoriert Buchstaben, solange X11 falsch ist. Das Bitte wiederholen Sie Ihre Eingabe kommt erst gar nicht. Ich glaube ich hab da immer noch was falsch vertsnaden oder weiß nicht wie ich es umsetzen soll.
Also nachdem er dass gelöscht hat, soll da Bitte wiederholen Sie Ihre Eingabe kommen und danach soll er X11 nochmal neu abfragen und diesmal Buchstaben ignorieren oder Buchstaben generell bei jeder Abfrage ignorieren.
Also müsste er ja nach der Schleife wieder nach oben springen, aber das geht doch nur mit goto, oder?Und selbst wenn ich jetzt eine 9 eingebe, bricht das Programm ab.
-
Du liest ja zwei mal von der Standardeingabe ein:
cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; cin>>X11; //loesch die Zeile while( !( std::cin >> X11 ) ) { //wenn du using namespace std geschrieben hast, ohne std:: davor cin.clear(); cin.ignore(numeric_limits<streamsize>::max()); cout<<"Bitte wiederholen Sie Ihre Eingabe!"<<endl; cout<<""<<endl; }
-
Achso, jetzt hab ich erst ganz verstanden, was das hinter while heißt

Aber wenn ich es jetzt kompiliere und dann einen Buchstaben eingebe, dann kommt danach gar nichts mehr.

EDIT: Aber wenn ich eine Zahl eingebe, dann macht das Programm normal weiter und rechnet auch mit der Zahl

Löscht der bei cin.clear(); eigentlich immer alle Variablen oder jetzt nur X11?
Weil ich würde die Schleife ja wenn schon hinter jede Abfrage schreiben.
-
cin.clear() löscht keine Variablen, es setzt lediglich den Fehlerzustand des Streams zurück.
-
Achso

Danke

Aber hat jemand noch einen Rat zu meinem Problem von weiter oben?
-
#include <limits> #include <iostream> using namespace std; int main() { cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; // cin >> X11; while( !(cin >> X11) ) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); // hier ein 2ter Parameter cout<<"Bitte wiederholen Sie Ihre Eingabe!"<<endl; cout<<""<<endl; } cin.get(); }cin.clearlöscht keine Variablen, es setzt den Fehlerzustand des Streamobjekts (in diesem Fallcinzurück).Warum hinter jede Abfrage schreiben?
Ich bin mir jetzt nicht 100% sicher, aber daswhile ( !( cin >> x11 ) )ist das selbe wie das
cin >> x11; while ( cin.fail() )und ersteres ist kürzer und ich weiß sofort was der Programmierer will.
PS: Falls das nicht stimmt, bitte korrigieren

-
Ja, stimmt nicht ganz.
Bei deiner Version wird die Schleife solange ausgeführt, solange !cin.fail() true ist. Die Einlese Operation findet nur einmal statt!
Richtig wäre:while (!(cin >> somewhat, cin.fail())) { }Auf das Ergebnis von cin >> somewaht, cin.fail() also für cin.fail() wird ! angewandt, was in der Bedingung der Schleife dann ausgewertet wird.
Bei der nächsten Iteration, wird cin >> somewaht wieder ausgeführt.
-
Achja, das hab ich übersehen. Danke Nathan

-
Jetzt sieht meins so aus, funktioniert aber so wie ganz am Anfang ohne die Schleife:
cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; while (!(cin>>X11, cin.fail())) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max()); cout<<""<<endl; cout<<"Bitte wiederholen Sie Ihre Eingabe:"<<endl; cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; }Funktioniert sogar noch weniger, bei Zahlen bricht es ab.
-
cout<<"Geben Sie die X Koordinate des ERSTEN Punktes der ERSTEN Geraden ein: "; while( !(cin >> X11) ) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); // hier ein 2ter Parameter cout<<"Bitte wiederholen Sie Ihre Eingabe!"<<endl; cout<<""<<endl;
-
Danke, danke, danke

Es funktioniert jetzt einwandfrei!!
Danke an euch 3
-
Hier ist jetzt der fertige Code: