Anfänger: Problem mit if-Anweisung
-
Hallo
Ich bin gerade bei Kapitel 5 Aufgabe 8 im Buch "Einführung in die Programmierung mit C++" von Bjarne Stroustrup und finde meinen Fehler nicht.
#include "std_lib_facilities.h" class input_exc {}; class too_many {}; class too_few {}; int main() { char exit = ' '; vector<int> numbers; int n; int how_much = 0; int sum = 0; cout << "Geben Sie beliebig viele Ganzzahlen ein! Abschließen mit [|]" << endl; while(exit != '|') { try { cin >> n; if(!cin) throw input_exc(); numbers.push_back(n); } catch(input_exc) { cin.clear(); cin >> exit; if(exit != '|') cout << "Eingabe nicht übernommen: Fehlerhafte Eingabe!" << endl; } catch(...) { cerr << "Unbekannter Fehler" << endl; } } exit = ' '; while(exit != '|') { cout << "\nWie viele der eingegebenen Zahlen sollen aufaddiert werden? Abbruch mit [|] "; try { cin >> how_much; if(!cin) throw input_exc(); else if (how_much > numbers.size()) throw too_many(); else if (how_much <= 0) throw too_few(); else if (how_much <= numbers.size() || how_much > 0) { for(int i = 0; i < how_much; ++i) { sum += numbers[i]; } cout << "Die Summe der ersten " << how_much << " Elemente: "; for(int i = 0; i < how_much; ++i) { cout << numbers[i] << " "; } cout << "ist " << sum << endl; exit = '|'; } else throw too_many(); } catch(input_exc) { cin.clear(); cin >> exit; if(exit != '|') cout << "Eingabe nicht übernommen: Fehlerhafte Eingabe!" << endl; } catch(too_few) { cout << how_much << " ??? Das ergibt keinen Sinn!" << endl; } catch(too_many) { cout << how_much << " ??? So viele Zahlen wurden garnicht eingegeben. Es sind insgesamt: " << numbers.size() << endl; } catch(...) { cerr << "Unbekannter Fehler" << endl; } } return 0; }Wenn ich nun eine negative Menge von Zahlen aufaddieren will, sollte z.B die Ausgabe "-3 ??? Das ergibt keinen Sinn!" ausgegeben werden. Wenn ich teste sieht das so aus:
~/cpp/buch$ ./Uebung8
Geben Sie beliebig viele Ganzzahlen ein! Abschließen mit [|]
12 23 34 45 56 |Wie viele der eingegebenen Zahlen sollen aufaddiert werden? Abbruch mit [|] -3
-3 ??? So viele Zahlen wurden garnicht eingegeben. Es sind insgesamt: 5Wie viele der eingegebenen Zahlen sollen aufaddiert werden? Abbruch mit [|]
Anscheinend meint meine Lösung das -3 > 5 ist. Ich suche jetzt seit Stunden und finde nichts. Ist bestimmt was ganz blödes. Wäre dankbar für eure Hilfe.
Gruß
dirac
-
Hallo dirac,
wenn Du den Code compilierst so liefert der Compiler Dir bereits 2mal eine Warnung:
Zeile 43: warning C4018: '>' : signed/unsigned mismatch
Zeile 45: warning C4018: '<=' : signed/unsigned mismatchDiese Warnungen solltest Du Ernst nehmen.
Bevor der Vergleich durchgeführt wird, wird der int '
how_much' in einen unsigned-Typ konvertiert und das ist eine ziemlich große Zahl.
Besser:else if (how_much > int(numbers.size())) throw too_many(); // Zeile 43Zeile 45 entsprechend ändern.
Gruß
Werner
-
Wieso machst Du das mit Exceptions?
Exception heisst Ausnahme. Du verwendest die aber zur Fallunterscheidung. Dafür sind Exceptions nicht gedacht.
Im Falle von -3 kommst Du in den else-Pfad in Zeile 60. -3 ist NICHT größer als 0.
-
MichelRT schrieb:
Wieso machst Du das mit Exceptions?
Exception heisst Ausnahme. Du verwendest die aber zur Fallunterscheidung. Dafür sind Exceptions nicht gedacht.
Vielleicht war das Sinn der Übung 8 (s.o.)
Falls nicht - so lassen sich für alle Freunde der for-Schleife die Zeilen 15 bis 34 durch folgenden Code ersetzen:
for( int n; cin >> exit && exit != '|' && cin.putback(exit) >> n; ) numbers.push_back( n );Gruß
Werner
-
MichelRT schrieb:
Im Falle von -3 kommst Du in den else-Pfad in Zeile 60. -3 ist NICHT größer als 0.
unsigned int(-3) aber schon...
-
Werner Salomon schrieb:
Hallo dirac,
wenn Du den Code compilierst so liefert der Compiler Dir bereits 2mal eine Warnung:
Zeile 43: warning C4018: '>' : signed/unsigned mismatch
Zeile 45: warning C4018: '<=' : signed/unsigned mismatchDiese Warnungen solltest Du Ernst nehmen.
Bevor der Vergleich durchgeführt wird, wird der int '
how_much' in einen unsigned-Typ konvertiert und das ist eine ziemlich große Zahl.
Besser:else if (how_much > int(numbers.size())) throw too_many(); // Zeile 43Zeile 45 entsprechend ändern.
Gruß
WernerDanke, das hat fast geklappt.
So wie du vorgeschlagen hast, funktioniert es bei mir nicht. Das Programm reagiert dann genauso wie vorher. Ich habe nun zwischen Zeile 40 und 41 eine weitere Zeile eingefügt.
int temp_size = numbers.size();Und temp_size entsprechend in die if Abfragen eingefügt. Das funktioniert. Den Gedanken dahinter mit unsigned habe ich wohl verstanden. Jetzt verstehe ich nur nicht, warum dein Vorschlag nicht funktioniert.
Die beiden Warnungen bekomme ich übrigens gar nicht. Die einzige Warnung, die ich bekomme, habe ich seitdem ich mit C++ angefangen habe:
/usr/include/c++/4.7/backward/backward_warning.h:33:2: warning: #warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date. Please use a non-deprecated interface with equivalent functionality instead. For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated. [-Wcpp]Bisher lief aber alles.
Ich benutze den Compiler "gcc version 4.7.2 (Debian 4.7.2-5)" auf Debian Wheezy.
Gruß
dirac
-
Werner Salomon schrieb:
MichelRT schrieb:
Wieso machst Du das mit Exceptions?
Exception heisst Ausnahme. Du verwendest die aber zur Fallunterscheidung. Dafür sind Exceptions nicht gedacht.
Vielleicht war das Sinn der Übung 8 (s.o.)
Falls nicht - so lassen sich für alle Freunde der for-Schleife die Zeilen 15 bis 34 durch folgenden Code ersetzen:
for( int n; cin >> exit && exit != '|' && cin.putback(exit) >> n; ) numbers.push_back( n );Gruß
WernerNaja, die Aufgabe verlangt dieses Programm zu schreiben und dann möglichst alle Fehler zu behandeln. Ich hatte das schon so mit den Exceptions verstanden. Werde mir dann das Kapitel wohl noch mal vor nehmen müssen. Danke für den Hinweis.
Den Vorgeschlagenen Ersatz für Zeile 15-34 verstehe ich jetzt auf Anhieb nicht. Bisher kam im Buch putback() auch noch nicht vor.
Gruß
dirac