PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Division durch 0 unterbinden



Terces
14.07.2009, 16:06
Bei einem kleinen Rechner wollte ich bei der Division eine teilung durch 0 mit einer while schleife unterbinden (ein bisschen was gelerntes ausprobieren/wiederholen).

zahl1, zahl2 sind int typen
schleife ist bool, sie wird am anfang auf true gesetzt.

[....]
cout <<"Bitte die erste Zahl eingeben : ";
cin >> zahl1;
while(schleife == true)
{
cout <<"Bitte die zweite Zahl eingeben : ";
if((cin >> zahl2) == 0)
{
cout << "Der Divisor darf nicht 0 sein!"<<endl;
continue;
}
schleife = false;
}
cout <<endl<<"Das Ergebnis der Division ist : "<<zahl1 / zahl2<<endl;
system("PAUSE");
return 0;
[....]Wenn ich bei der zweiten Zahl allerdings 0 eingebe, hängt sich das Programm mit einer Windows typischen Senden / Nicht Senden Meldung auf.

Kann mir einer sagen woran das liegt ? ^^
Habe schon verschiedene Methoden für die if-überprüfung genommen, hat auch nicht geholfen.

Edit: Alles klar gelöst - hatte was mit cin in der if bedingung zu tun.

nathex
14.07.2009, 16:43
Auch wenn du es schon selbst gelöst hast, schreib ichs mal hier rein.
Wozu eine while Schleife benutzen, wenn dass alles viel problemloser und einfacher mit einer normalen if-Abfrage geht (da zahl2 ja praktisch nie eine 0 sein soll).

Hier so wäre die einfachste Lösung:


#include <iostream>
using namespace std;

int main(void)
{
int zahl1, zahl2;

cout << "Erste Zahl\n";
cin >> zahl1;

cout << "Zweite Zahl\n";
cin >> zahl2;

if( zahl2 == 0 )
{
cerr << "Zahl 2 darf nicht = 0 sein!\n";
exit(1);
}

cout << "Die Division aus " << zahl1 << " und " << zahl2 << " ist gleich: " << (zahl1/zahl2) << "\n";

system("pause");
return 0;
}


Und dann kannst du zusätzlich den Code noch verbessern, indem du die Eingaben von zahl1 und zahl2 auf ihre richtigkeit überprüfst (damit meine ich, dass du Überprüfst, dass bei zahl1 oder zahl2 kein falscher Wert (z.b. ein Buchstabe) eingegeben wird)

Das könntest du dann so machen:

#include <iostream>
using namespace std;


int main(void)
{
int zahl1, zahl2;

cout << "Erste Zahl\n";

if( ! ( cin >> zahl1 ) )
{
cerr << "Fehlerhafte Eingabe!\n";
exit(1);
}

cout << "Zweite Zahl\n";

if( ! ( cin >> zahl2 ) )
{
cerr << "Fehlerhafte Eingabe!\n";
exit(1);
}

if( zahl2 == 0 )
{
cerr << "Zahl 2 darf nicht = 0 sein!\n";
exit(1);
}

cout << "Die Division aus " << zahl1 << " und " << zahl2 << " ist gleich: " << (zahl1/zahl2) << "\n";

system("pause");
return 0;
}

Das normale cin wurde (in dem rot markierten) in eine if-Funktion eingeschlossen!
In dieser wird überprüft ob der Wert von cin = true ist, ansonsten wird die Fehlermeldung ausgegeben!

EBFE
14.07.2009, 17:26
cin >> operand sollte sich selbst (CIN) returnen. Also eigentlich eine Refernz auf cin bzw istream. Und die ist nicht 0, sofern der Einlesevorgang erfolgreich war, so dass if(cin>>bla)==0) niemals greift ;).

ist nicht alles ganz so einfach, weil es auch "überladene" Operatoren wie ! gibt. Stiftet imho mehr Verwirrung bzw. Unklarheit, was nun greift (Compiler/Sprachinternes ! oder halt das vom Object) - aber die c++ sind ja stolz darauf ;)

Terces
14.07.2009, 18:07
@nathex

Ich wollte eigentlich das man die zweite zahl nochmal eingeben kann wenn man eine 0 hatte, deswegen die while-schleife.
Die Fehlerausgabe bei falscher Eingabe hatte ich schon gelernt, war aber halt grade an der schleife und hatte dies nochnicht drinne.
Was ich aber endlich verstanden hab was \n genau bringt ^^ (habe es für einen Tabulator gehalten der 4-5 leerzeichen macht).

@Topic

Ist das auch der Grund warum bei folgendem code die eingabe eines Buchstabens in einer Endlosschleife endet ?


#include <iostream>
using namespace std;

int zahl1, zahl2;

int main(void)
{
while (true)
{
cout <<"Bitte die erste Zahl eingeben : ";
if ( ! (cin >> zahl1))
{
cerr << "Fehlerhafte Eingabe, Nur Ganze Zahlen eingeben!\n";
continue;
}
break;
}
while (true)
{
cout <<"Bitte die zweite Zahl eingeben : ";
if ( ! (cin >> zahl2))
{
cerr << "Fehlerhafte Eingabe, Nur Ganze Zahlen eingeben!\n";
continue;
}
if(zahl2 == 0)
{
cerr << "Der Divisor darf nicht 0 sein!\n";
continue;
}
break;
}
cout <<"\nDie Division aus "<<zahl1<<" und "<<zahl2<<" ist gleich: "<<zahl1 / zahl2<<" Rest "<<zahl1 % zahl2<<"\n";
system("PAUSE");
return 0;
}

nathex
14.07.2009, 19:11
Ich wollte eigentlich das man die zweite zahl nochmal eingeben kann wenn man eine 0 hatte, deswegen die while-schleife.
Achso, ok das habe ich falsch verstanden.

Also: Du kannst dies mit der "normalen" while Schleife nur sehr unprofessionell bewerkstelligen. Ich würde dir zu deinem Projekt eher zur do-while Schleife raten. Das ist wohl die professionellste Methode
Ich hab dir hier mal das Programm geschrieben, wie du es (hoffentlich) haben willst.

Diesmal in Form von einem Screenshot, da ich die Quote hier viel zu unübersichtlich für einen Code finde:

http://www4.picfront.org/picture/JQLh2qJWKQ/img/code.png

Ich denke mal, dass du alle wichtigen Informationen meinen Kommentaren im Quellcode entnehmen kannst, ansonsten kannst du gerne fragen :)

Gruß, nathex

Terces
14.07.2009, 21:54
Stimmt, eine do-while Schleife eignet sich hier wirklich besser, man brauch das ja mindestens einmal, Danke. ^^

Die einzige Frage die ich dann noch hätte wäre wiegesagt warum mein zuletzt geposteter Code nicht funktioniert, und das Programm bei einem Buchstaben nicht ordnungsgemäß zurückspringt.

nathex
15.07.2009, 00:47
Danke. ^^

Gerngeschehen ;)


Die einzige Frage die ich dann noch hätte wäre wiegesagt warum mein zuletzt geposteter Code nicht funktioniert, und das Programm bei einem Buchstaben nicht ordnungsgemäß zurückspringt.

Ich habe deinen Quellcode mal neugeschrieben, so wie ich es für richtig halte, da ich grade keine Lust hatte deinen Code auf potenzielle Fehler zu untersuchen :)
Ich denke mal, dass kannst du auch selber machen, wenn du meinen jetzt folgenden Code zum Vergleich nimmst.

Hier ist ein Screen, wie ich es geschrieben hab:

http://www.imgwelt.de/uploads/1ZQ0DAJCD0L.bmp

Denke mal, die Kommentare sollten da wieder alles nötige erklären.

greetZ

//edit: Bei der zweiten if-funktion in der while-schleife sollte eigendlich ein cerr, statt einem cout stehen. Aber im Prinzip ist das egal :)

//edit2: Hab mir nun doch mal deinen Code angesehn. Deiner kann so nicht richtig funktioniere, da sich die while Schleifen während der abfrage praktisch gegenseitig ausspielen und es so zur endlosschleife wird.
Benutze meine Methode. Ich glaube nicht, dass es mit deiner in irgendeiner weise geht :Y

Terces
15.07.2009, 06:26
//edit2: Hab mir nun doch mal deinen Code angesehn. Deiner kann so nicht richtig funktioniere, da sich die while Schleifen während der abfrage praktisch gegenseitig ausspielen und es so zur endlosschleife wird.
Benutze meine Methode. Ich glaube nicht, dass es mit deiner in irgendeiner weise geht :Y

So richtig begreif ich das zwar nicht (also das warum), aber ich versteh es bestimmt zu gegebener Zeit selber.

Bin dann soweit Fertig, Ty. :)

nathex
15.07.2009, 07:27
Die Sache ist die: Deine Codes sind durchaus richtig (bis auf kleine Schönheitsfehler), allerdings machst du es dir selbst zu kompliziert. Und das Ziel eines Programmierers ist es, den Programm-Quellcode so verständlich und sinnvoll wie möglich zu machen.

Aber ich denke, wenn du weiter C++ lernst, wirst du das schon alles hinbekommen ;)


Bin dann soweit Fertig, Ty.
Bin immer für neue Fragen offen ;)

EBFE
15.07.2009, 09:47
Die einzige Frage die ich dann noch hätte wäre wiegesagt warum mein zuletzt geposteter Code nicht funktioniert, und das Programm bei einem Buchstaben nicht ordnungsgemäß zurückspringt.




int main(void)
{
while (true)
{
cout <<"Bitte die erste Zahl eingeben : ";
if ( ! (cin >> zahl1))
{
cerr << "Fehlerhafte Eingabe, Nur Ganze Zahlen eingeben!\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
continue;
}
break;
}
while (true)
{
cout <<"Bitte die zweite Zahl eingeben : ";
if ( ! (cin >> zahl2))
{
cout << "Fehlerhafte Eingabe, Nur Ganze Zahlen eingeben!\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
continue;
}

if(zahl2 == 0)
{
cerr << "Der Divisor darf nicht 0 sein!\n";
continue;
}
break;
}
cout <<"\nDie Division aus "<<zahl1<<" und "<<zahl2<<" ist gleich: "<<zahl1 / zahl2<<" Rest "<<zahl1 % zahl2<<"\n";
system("PAUSE");
return 0;
}




so sollte es laufen. Hintergrund:
probiere mal aus bei der ersten Zahl sowas wie "2B" einzugeben. Die Fehlermeldung wirst du für die zweite Eingabe bekommen. Denn afaik extrahiert >> "soviel es kann" heraus. Der Rest bleibt im Buffer. Bei dem vorherigen Code


while (true)
{
cout <<"Bitte die zweite Zahl eingeben : ";
if ( ! (cin >> zahl2))
{
cout << "Fehlerhafte Eingabe, Nur Ganze Zahlen eingeben!\n";

continue;
}
hatte es nämlich das Problem, dass die fehlerhafte Eingabe nicht in eine Zahl umgewandelt werden konnte (CIN gab Error zurück) - und daher im Buffer verblieb. Und dann wurde der Versuch vom neuen unternommen - da im Buffer noch was verblieben war, wurde auch keine neue Benutzereingabe eingelesen.

Daher sollte man nach der Fehleingabe erstmal "flushen/skippen" um wieder Platz für eine neue zu machen. Außerdem alle Fehlerflags per cin.clear(); zurücksetzen.

nathex
15.07.2009, 10:10
Grml genau das hatte ich vorhin versucht, kannte aber cin.clear() noch nicht.
Dadurch ist ja das Problem im Prinzip behoben :)

Terces
15.07.2009, 10:55
so sollte es laufen.

Jop, klappt alles.
Danke euch beiden, das Problem ist ja nun umfassend gelöst, cin werd ich mir auch nochmal genauer angucken. ^^

blackberry
15.07.2009, 12:43
Dann wurde hier ja alles gesagt.

/closed