PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Integereingabe


BodyLove
2006-02-01, 15:31:20
Hey hi,

ich habe hier ein Programm, welches über eine While Schleife und einer Switch-Case-Anwendung eine Menue simulieren soll.

Der User wählt dann eine Zahl aus, um den gewünschten Befehl auszuführen. die Variable hierfür ist eine Integer-Variable. Wenn ich jetzt statt einer Zahl einen Buchstaben eingebe, bin ich in einer Endlosschleife. Wie kann ich dies umgehen? Mit try-catch habe ich versucht, aber nicht hingekriegt.

Die Eingabe habe ich auch als char Eingabe initialisiert, nur kann ich hier 123 eingeben, und er geht aber dabei in Menuepunkt 1 rein, und durchläuft die Routine 2 weitere male.

Ich hoffe ich habe meine Problemematik einigermaßen gut rübergebracht. Ich danke schon vorab für Hilfeversuche.

Gruß Memo

noid
2006-02-01, 15:38:03
mach doch beim Switch/case einfach ein "default:" damit fängst du die Ausnahmen einfach ab.


switch (Ausdruck)
{
case K1:
Aktion1
[break;]
case K2:
Aktion2
[break;]
....
case Kx:
AktionX
[break;]
[default:
AktionY]
}

BodyLove
2006-02-01, 15:47:48
hi,

nein. Das default fängt ja nur integerwerte ab, die nicht mit case abgefangen wurden. Das System erwartet eine Integereingabe, aber der Nutzer gibt einen Buchstaben ein. Hier ist das Problem. Das kann ich mit default nicht abfangen. Und mit if, try Catch konnte ich es auch nicht.

Ich weiß nicht, was ich da machen kann.:(

Danke dir für die Mühe.:)


while (!exit)
{
{
cout<<"\nMenue:"<<endl;
cout<<" 1. einlesen:"<<endl;
cout<<" 2. ausgeben:"<<endl;
cout<<" 3. Alle Jungs ausgeben:"<<endl;
cout<<" 4. Alle Maedchen ausgeben: "<<endl;
cout<<" 5. Bestimmte Stelle loeschen:"<<endl;
cout<<" 6. Suchen Loeschen:"<<endl;
cout<<" 7. Sortiere Liste nach Jahr:"<<endl;
cout<<" 0. Abbrechen: "<<endl;
cin>>eingabe;
switch(eingabe)
{
case 1:

cout<<"Bitte geben sie den Vornamen ein: ";
cin>>vname;
cout<<"\nBitte geben sie den Nachnamen ein: ";
cin>>nname;
cout<<"\nBitte geben sie das Geschlecht ein (m/w): ";
cin>>g;
cout<<"\nBitte geben sie den Geburtstag ein: ";
cin>>t;
cout<<"\nBitte geben sie den Geburtsmonat ein: ";
cin>>m;
cout<<"\nBitte geben sie das Geburtsjahr ein: ";
cin>>j;
einlesen(vname,nname,g,t,m,j);
break;
case 2:
ausgeben();
break;
case 3:
jungen();
break;
case 4:
maedchen();
break;
case 5:
int x;
cout<<"Welche Stelle soll geloescht werden: ";
cin>>x;
del(x);
break;
case 6:
cout<<"Welches Geschlecht soll geloescht werden: ";
cin>>v;
suchendel(v);
break;
case 7:
sortiereliste();
break;
case 0:
exit=true;
break;
default:
cout<<"Ihre Eingabe ist falsch, erneut versuchen: ";
break;
};

noid
2006-02-01, 15:54:21
ist "eingabe" auch vom Typ int? Ansonsten kannst du auch getch() benutzen (anstatt cin).

Matrix316
2006-02-01, 16:03:44
Frag einfach ob eingabe in einem int Bereich liegt. Da char aber im Prinzip auch int ist...musste halt gucken. ;)


do{
cin>>eingabe;
}while(eingabe<0 || eingabe>7);

noid
2006-02-01, 16:06:29
Frag einfach ob eingabe in einem int Bereich liegt. Da char aber im Prinzip auch int ist...musste halt gucken. ;)


do{
cin>>eingabe;
}while(eingabe<0 && eingabe>7);


gibt das nicht ne Warning, wenn man char mit int vergleicht ohne cast?

BodyLove
2006-02-01, 16:12:56
@noid

ja, eingabe war bis jetzt auch int. Getch() habe ich bis jetzt nicht gehört, bin in der hinsicht noch anfänger, aber habe ich habe mit Getch() und Google die fkt fflush(stdin) gefunden, der den Tastaturpuffer löscht, und somit ich diesen fehler umgehe. Ist zwar nicht elegant, aber zumindest dann fehlerfrei.;(

@matrix

das problem ist/war, dass wenn ich eingabe mit int initialisiere, ich keine Buchstaben eingeben kann. Mit char kann ich zwar buchstaben eingeben, aber der Tastaturpuffer war nicht gelöscht.

Will heißen, wenn ich char eingabe mache und 123 eingebe, dann springt er nicht nur ins erste Menü, sondern auch in die dazugehörigen abfragen.:)


Jetzt muss ich nur dem User zwingen, dass er nicht mehr als 1 Stelle für die eingabe hat. Wenn ich 123 eingebe, springt er noch da rein.:|

weiß einer rat. Ich suche schon im google.

Noid und Matrix, vielen dank.:)

Matrix316
2006-02-01, 16:16:29
Ist "eingabe" vom Typ char? Könnte man ja auch als int Variable machen. Da aber char quasi int ist, sollte es aber trotz einer eventuellen Warnung keine Probleme geben.

Matrix316
2006-02-01, 16:20:26
@matrix

das problem ist/war, dass wenn ich eingabe mit int initialisiere, ich keine Buchstaben eingeben kann. Mit char kann ich zwar buchstaben eingeben, aber der Tastaturpuffer war nicht gelöscht.

Willst du unbedingt Buchstaben eingeben lassen? Du fragst ja mit "eingabe" nur von 0 bis 7 ab, oder?

Es geht ja auch beides mit verschiedenen Variablen:

String text; oder char *text;
int eingabe;

cin >> text;
cin >> eingabe;

es geht sogar laut c Referenz beides, also cin >> text >> eingabe;


Will heißen, wenn ich char eingabe mache und 123 eingebe, dann springt er nicht nur ins erste Menü, sondern auch in die dazugehörigen abfragen.:)

Mit der do-while abfrage von oben, würden nur 1-7 als eingabe gehen, ansonsten wiederholt er die abfrage. Oder willst du noch mehr abfragen?

Jetzt muss ich nur dem User zwingen, dass er nicht mehr als 1 Stelle für die eingabe hat. Wenn ich 123 eingebe, springt er noch da rein.:|

Siehe do-while abfrage. ;)

BodyLove
2006-02-01, 16:38:51
die do while funktioniert ja nur, wenn ich Integerwerte habe. Selbst dann funktioniert diene Abfrage in C++ nicht, zumindest bei mir.:|


#include <iostream>
using namespace std;
void main()
{
int eingabe;
do{
cin>>eingabe;
cout<<eingabe;
}while(eingabe<0&&eingabe>7);
}


so will er nicht, frag mich nicht wieso.


Was ich wollte habe ich ja. Nur der Prof bat mich, das Programm auch Narrensicher zu machen. Das Programm verlangt nach zahlen, eingegeben wird aber dafür ein Buchstabe. Wenn ich eingabe mit int initialisiere, dann gibt es ne endlosschleife, auch bei deinem kleinen Programm von eben.;)

Mit Char habe ich das Problem, dass ich eine char eingabe[1] machen kann, die Switchanweisung auch funktioniert. Bei eingabe[2] zickt er ja schon rum. Nur besteht das Problem, dass ich mehr als nur eine stelle eingeben kann. Das möchte ich nun unterbinden. Ich möchte nur eine Stelle für die Eingabe haben. Dann habe ich diese Probleme nämlich nicht mehr.:)

Gast
2006-02-01, 16:45:25
Könnt ihr bitte ruhig sein wenn ihr keine Ahnung habt?

@Topic: Man kann mit Standard-C++ nicht verhindern dass jemand ungültige Eingaben macht, aber man kann es behandeln wenn Enter gedrückt wurde.

1. Möglichkeit: Exceptions
cin.exceptions(ios::badbit | ios::failbit);
try {
int i;
cin >> i;
cout << i * i;
} catch(exception const& error) {
cin.clear();
cout << "Oops: " << error.what() << "\n";
}

2. Möglichkeit: Direkt per Failbits:
[code]int i;
cin >> i;
if(cin.fail() || cin.bad()) {
cout << "Du bist wohl zu dumm zum Zahlen eingeben!";
cin.clear();
}
else {
cout << i * i;
}[/cpp]

Ich empfehle Variante 1!

Trap
2006-02-01, 16:45:56
Eingabestreams sind nicht sehr intuitiv. Dadurch dass man Puffer und Zustände hat und Leseoperationen fehlschlagen können muss man genauer überlegen wie man etwas hinbekommt.

do {
if(!(cin >> eingabe)){
// cin.clear(); bin mir nicht sicher ob man das braucht, probier einfach mal aus
cin.sync();
}
}while(eingabe<0&&eingabe>7);
sollte funktionieren (ist aber ungetestet).

Gast
2006-02-01, 16:46:02
grgr verdammt hab das zweite mal /cpp geschrieben -.-

pancho
2006-02-01, 16:48:25
if (!cin.fail())
{blubb}
else
{foobar}


Versuchs mal damit, eventuell nochmal danach googeln. Ist schon etwas länger her bei mir.
edit: Mist, zu spät.

noid
2006-02-01, 16:48:58
cout<<" 6. Suchen Loeschen:"<<endl;
cout<<" 7. Sortiere Liste nach Jahr:"<<endl;
cout<<" 0. Abbrechen: "<<endl;

eingabe=getch();

switch(eingabe)
{
case '1':
cout<<"Bitte geben sie den Vornamen ein: ";
cin>>vname;
cout<<"\nBitte geben sie den Nachnamen ein: ";
cin>>nname;
cout<<"\nBitte geben sie das Geschlecht ein (m/w): ";
cin>>g;
cout<<"\nBitte geben sie den Geburtstag ein: ";
cin>>t;
cout<<"\nBitte geben sie den Geburtsmonat ein: ";
cin>>m;
cout<<"\nBitte geben sie das Geburtsjahr ein: ";
cin>>j;
einlesen(vname,nname,g,t,m,j);
break;
case '2':
ausgeben();
break;
case '3':
jungen();
break;
{...}



wenn eingabe ein char ist, dann solltest du das auch so überprüfen.

Trap
2006-02-01, 16:49:39
Ich halte mit fail und bad rummachen für hässlich.

Gast
2006-02-01, 16:52:20
Ich halte mit fail und bad rummachen für hässlich.

Man du bist ja hochintelligent. Mal drüber nachgedacht dass operator! bzw. operator void* den genau gleichen Effekt hat wie die Methode fail() (bzw. !fail()).

Des weiteren ist es sogar deutlicher wenn man !cin.fail() schreibt anstatt nur if(cin >> x).

Greetings

Trap
2006-02-01, 16:54:30
Man du bist ja hochintelligent.
Finde ich auch, schön das du meiner Meinung bist ;D

Am besten ist sowieso isTrue(!cin.fail() == !false) mit isTrue aus http://thedailywtf.com/forums/43457/ShowPost.aspx :wink:

BodyLove
2006-02-01, 16:55:52
Ich danke für eure Antworten.:)

Bin aber jetzt fündig geworden. ich nutze nun zum einlesen die Funktion
"scanf("%d", &eingabe);", anstatt "cin". damit funktioniert es einwandfrei. Eingabe ist als Integer initialisiert, und er gibt Default-Routine wider, selbst, wenn ich einen Buchstaben eingebe.

Ich werde aber alle Tipps jetzt nachgehen. Ich merke, ich habe Defizite.:)

Gast
2006-02-01, 17:01:04
Mach das nicht!! Die C Ein-/Ausgabefunktionen sind nur bedingt mit den C++ Streams kompatibel. Genauso wie getch() keine Standard-C++ Funktion ist.

BodyLove
2006-02-01, 17:04:43
danke für die Warnung. Ich schaue mir auch alle anderen Vorschläge an, bzw. hoffe es lauffähig zu bekommen. Der Support eurerseits ist echt toll.

Matrix316
2006-02-01, 17:54:54
Eingabestreams sind nicht sehr intuitiv. Dadurch dass man Puffer und Zustände hat und Leseoperationen fehlschlagen können muss man genauer überlegen wie man etwas hinbekommt.

do {
if(!(cin >> eingabe)){
// cin.clear(); bin mir nicht sicher ob man das braucht, probier einfach mal aus
cin.sync();
}
}while(eingabe<0&&eingabe>7);
sollte funktionieren (ist aber ungetestet).
Mach nicht den Fehler wie ich am Anfang mit eingabe<0 && eingabe>7 (habs nachträglich noch editiert), denn das wird nicht gehen, weil eingabe nie gleichzeitig <0 und >7 ist, sondern das muss man schon mit || (=oder) testen.

Trap
2006-02-01, 17:58:03
Ups, copy&paste ohne den Inhalt zu lesen kann schief gehen :tongue:

GloomY
2006-02-01, 19:41:01
Frag einfach ob eingabe in einem int Bereich liegt. Da char aber im Prinzip auch int ist...musste halt gucken. ;)


do{
cin>>eingabe;
}while(eingabe<0 || eingabe>7);
Wenn "eingabe" vom Typ char ist, dann musst du mit dem ASCII-Code vom Zeichen Null vergleichen und nicht mit der Zahl Null (das gleiche gilt für den Test mit 7).

Damit du jetzt nicht in der Tabelle nachschauen musst, welchen Wert diese beiden Zeichen haben, lass' es am Besten den Compiler selbst machen: ;)

do{
cin>>eingabe;
}while(eingabe<'0' || eingabe>'7');

Matrix316
2006-02-01, 20:52:15
Aber warum soll man eine Zahl mit einer char Variable abfragen... :confused: :rolleyes:

ScottManDeath
2006-02-01, 23:01:56
Aber warum soll man eine Zahl mit einer char Variable abfragen... :confused: :rolleyes:

Weil für Menüs mit weniger als 11 Optionen eine Ziffer ausreicht, bequemerweise haben die Ziffern 0 bis 9 auch entsprechende ASCII Represäntationen: '0' + 0 bis '0' + 9 ;)