Anfängerfragen: Warum rutscht er immer in die Elseschleife, warum wiederholt er die Sprungmarke...
-
Hallo,
ich bin ein C++ Anfänger, habe folgendes Programm geschrieben:
#include <iostream> using namespace std; int main() { int iW, iPunkte, iNote; cout << "Notenumrechnung" <<endl <<endl; //Ueberschrift cout << "Wollen sie ihre Punkte in eine Note umrechnen (1) oder umgekehrt (2)? "; //anfang: //Sprungmarke cin >> iW; if(iW==1){ //Schleife für Umrechnung Punkte in Note //punkte: //Sprungmarke cout << "\n\nGeben sie ihre Punkte ein: "; cin >> iPunkte; cout << endl<< "Note: "; switch (iPunkte){ case 0: cout << "6"; break; case 1: case 2: case 3: cout << "5"; break; case 4: case 5: case 6: cout << "4"; break; case 7: case 8: case 9: cout << "3"; break; case 10: case 11: case 12: cout << "2"; break; case 13: case 14: case 15: cout << "1"; break; default: cout << "Es ist nur ein Wert zwischen 0-15 erlaubt"; //goto punkte; //zurueck zur Punkteabfrage } } if(iW==2){ //Schleife für Umrechnung Note in Punkte //note: //Sprungmarke cout << "\n\nGeben sie ihre Note ein (+ und - erlaubt): "; cin >> iNote; cout << endl<< "Punkte: "; switch (iNote) { //case '1+': // cout << "16 (theoretische Note)"; // break; case 1: cout << "15"; break; //case 1-: // cout << "14"; // break; //case 1-2: //case 1.5: //case 1,5: // cout << "13"; // break; //case 2+: // cout << "12"; // break; case 2: cout << "11"; break; //case 2-: //case 2-3: //case 2.5: //case 2,5: // cout << "10"; // break; //case 3+: // cout << "9"; // break; case 3: cout << "8"; break; //case 3-: // cout << "7"; // break; //case 3-4: //case 3.5: //case 3,5: //case 4+: // cout << "6"; // break; case 4: cout << "5"; break; //case 4-: // cout << "4"; // break; //case 4-5: //case 4.5: //case 4,5: //case 5+: // cout << "3"; // break; case 5: cout << "2"; break; //case 5-: //case 5-6: //case 5.5: //case 5,5: // cout << "1"; // break; case 6: cout << "0"; break; default: cout << "Fehler! Bitte geben sie einen Wert zwischen 1 und 6 ein, +, - und Halbzahlen erlaubt."; //goto note; //zurueck zur Notenabfrage } } else { //zurueck zum Anfang wegen Fehleingabe cout << "\n\nBitte korrigieren sie ihre Eingabe! (1) oder (2)? "; //goto anfang; } //------------------------------------------------------------------------------ cout << endl<<endl; system("PAUSE"); return EXIT_SUCCESS; }Also, einmal rutscht er imer in die Elseschleife, ich möchte aber nur, das er in die Elseschelife rutscht wenn irgendwas anderes eingegeben wird außer 1 oder 2...und dann führt er die Sprungarken immer aus, obwohl er theoretisch an die entsprechenden Stellen doch garnicht kommen dürfte, wenn vorher uterbrochen wird, und wenn mir noch jemand sagen kann, wie ich das Löse, dass ich auch 1+, 2.5, usw. im case benutzen kann, ich hab es schon probiert einzukästeln '1+', dann ignoriert er das + einfach und spuckt die Ausgabe für 1 aus und wenn ich iNote als "char" notiere, dann klappt das ganze nicht.
Danke für die Hilfe. Bis dann.
-
puh
kann sein das er bei cin auch noch das "\n" mit nimmt
sprich bei "eins + return"
"1\n"
ein switch kann keine strings bzw char unterscheiden.
ist bei deinem programm auch unlogisch, da du von punkte zu note auch keine 1+ oder so hast, aber bei note zu punkte willst es haben
ich glaube du kannst dein
case 1: und case 2: weglassen und nur
case 0: cout << "6"; break; case 3: cout << "5"; break; case 6: cout << "4"; break; case 7: case 8: case 9: cout << "3"; break; case 12: cout << "2"; break; case 15: cout << "1"; break;so jetzt muss ich was aus dem ofen holen

-
c_PA schrieb:
Hallo,
ich bin ein C++ Anfänger, habe folgendes Programm geschrieben:
...Bei solchen Sachen kann es von Vorteil sein, eine eigene Klasse zu schreiben, die das Einlesen und Ausgeben eines nicht trivialen Wertes übernimmt. Z.B. so:
#include <iostream> #include <cassert> class Note { public: explicit Note( int punkte = 0 ) : m_punkte( punkte ) { assert( m_punkte >= 0 && m_punkte <= 15 ); } // -- Note einlesen friend std::istream& operator>>( std::istream& in, Note& note ) { int n; if( in >> n ) { if( n < 1 || n > 6 ) { in.setstate( std::istream::failbit ); return in; } int punkte = 17 - 3*n; // Note in Punkte umrechnen // -- optional anhängendes +/- einlesen typedef std::istream::traits_type traits_type; traits_type::int_type c = in.rdbuf()->sgetc(); if( !traits_type::eq_int_type( c, traits_type::eof() ) ) { const char plusminus = traits_type::to_char_type( c ); if( plusminus == '+' || plusminus == '-' ) { in.rdbuf()->sbumpc(); // +/- konsumieren punkte += (plusminus == '+')? 1: -1; // Note korrigieren } } if( punkte < 0 ) punkte = 0; // weniger geht nicht note.m_punkte = punkte; } return in; } // -- Note ausgeben friend std::ostream& operator<<( std::ostream& out, const Note& note ) { const int rest = note.m_punkte % 3; // +/- return out << (18 - note.m_punkte)/3 // Note aus Punkten << (rest == 0 && note.m_punkte != 0? "+": ( rest == 1? "-": "" )); } int Punkte() const { return m_punkte; } private: int m_punkte; };Die Anwendung im main dann bitte nicht mit goto's sondern mit Schleifen (for, while, usw.) erledigen. *** **** **** **** ************* ***** ************ ***********.
int main() { using namespace std; cout << "Notenumrechnung" <<endl <<endl; //Ueberschrift for(;;) // Beenden mit break (s.u.) { cout << "Wollen sie ihre Punkte in eine Note umrechnen (1) oder umgekehrt (2)? "; int iW; if( !(cin >> iW) ) break; switch( iW ) { case 1: // Punkte nach Note { cout << "\nGeben sie ihre Punkte ein: "; int punkte; if( cin >> punkte && punkte >= 0 && punkte <= 15 ) { cout << "Note: " << Note( punkte ) << endl; } else cerr << " .. es sind nur 0 bis 15 Punkte zulaesig" << endl; } break; case 2: // Note in Punkte { cout << "\nGeben sie ihre Note ein: "; Note note; if( cin >> note ) { cout << note.Punkte() << " Punkte" << endl; } else cerr << " .. bitte Note eingeben; z.B. 3+" << endl; } break; default: cerr << " .. nur 1 oder 2 eingeben" << endl; } cout << endl; cin.clear(); } return 0; }Viel Spaß damit;
Gruß
Werner
-
BTW: Es gibt keine Else-Schleife. Man erzählt von der else-Klausel der if-Abfrage. Schleifen führen zu wiederholten Ausführungen.
MfG SideWinder
-
Auf jeden Fall ist Deine if-else-Konstruktion nicht ganz sauber.
c_PA schrieb:
if(iW==1){ //Schleife für Umrechnung Punkte in Note } if(iW==2){ //Schleife für Umrechnung Note in Punkte } else { //zurueck zum Anfang wegen Fehleingabe cout << "\n\nBitte korrigieren sie ihre Eingabe! (1) oder (2)? "; //goto anfang; }Wenn iW gleich 1 ist, ergibt die Abfrage if(iW==2) false und die Anweisungen unter else werden ausgeführt.
if( iW == 1) { } else if( iW == 2 ) { } else { }Das müsste gehen.
-
asdf__:) schrieb:
case 1: und case 2: weglassen und nur
case 0: cout << "6"; break; case 3: cout << "5"; break; ...Das dürfte eher kontraproduktiv sein - such dir mal eine Erläuterung zur Funktion von switch/case in C(++).
-
ok nicht ganz
aber schau dir mal das bsp an, und sag was da kontraproduktiv ist
Es ist nicht möglich, Bereiche von Werten direkt als case -Marken zu verwenden, also etwa eine case -Marke für Werte von 10 bis 19 zu schreiben. Hierfür müssen alle Werte als case -Marke aufgezählt werden. Wenn das nicht erwünscht ist, bleibt noch die Möglichkeit, vorher den Bereich zu ermitteln, wie in dem folgenden Beispiel, das für Zahlen von 10 bis 20, für Zahlen von 20 bis 29 und für die Zahlen 30 und 31 jeweils unterschiedliches Verhalten zeigt. bereiche.cpp #include <iostream> #include <ostream> void bereiche( int const zahl ) { switch( zahl < 30 ? zahl < 20 ? 10 : 20 : zahl ) { case 10: std::cout << "Bereich von 10 bis 19"; break; case 20: std::cout << "Bereich von 20 bis 29"; break; case 30: std::cout << "Zahl 30"; break; case 31: std::cout << "Zahl 31"; break; }} int main() { for( int i = 10; i < 32; ++i ) { std::cout << i << ": "; bereiche( i ); std::cout << '\n'; }} std::cout 10: Bereich von 10 bis 19 11: Bereich von 10 bis 19 12: Bereich von 10 bis 19 13: Bereich von 10 bis 19 14: Bereich von 10 bis 19 15: Bereich von 10 bis 19 16: Bereich von 10 bis 19 17: Bereich von 10 bis 19 18: Bereich von 10 bis 19 19: Bereich von 10 bis 19 20: Bereich von 20 bis 29 21: Bereich von 20 bis 29 22: Bereich von 20 bis 29 23: Bereich von 20 bis 29 24: Bereich von 20 bis 29 25: Bereich von 20 bis 29 26: Bereich von 20 bis 29 27: Bereich von 20 bis 29 28: Bereich von 20 bis 29 29: Bereich von 20 bis 29 30: Zahl 30 31: Zahl 31
-
Klar, wenn du die switch-Anweisung entsprechend anpasst, mag das ja gehen. Aber dann mußt du auch dazusagen, WIE sie aussehen sollte. (wenn man deine "Verbesserung" in den Originalcode einsetzen würde, käme für 1,2,4,5,... gar keine Ausgaben mehr)
-
Hallo,
@all: vielen Dank für die Antworten! Echt klasse das ihr euch die Zeit nehmt.
@Werner Salamon: Danke für die ausführliche Ausarbeitung, leider verstehe ich diesen Programmablauf noch nicht, soweit bin ich nocht nicht
werd mich mal durcharbeiten und versuchen zu verstehen was da vorgeht.@asdf: Ja klar, in eine Richtung möchte ichs in die andere nicht
liegt nur daran das ich mir eine Aufgabe gestellt habe und ein paar Schwierigkeiten reinbauen wollte, die ich lösen muss, ob das wirklich Sinnvoll ist, sei daheingestellt, aber danke auf alle Fälle.@GV: Danke, das werde ich mal versuchen, hab halt erst angefangen mit else/if und muss da noch bisschen routinieren wann ich was einsetze.
-
c_PA schrieb:
@Werner Salamon: Danke für die ausführliche Ausarbeitung, leider verstehe ich diesen Programmablauf noch nicht, soweit bin ich nocht nicht
werd mich mal durcharbeiten und versuchen zu verstehen was da vorgeht.es freut mich, dass Du Dich nochmal meldest. Du hast Recht, mein Beispiel war wohl bißchen viel auf einmal. Wenn Dich das eine oder andere interesssiert, so frag' Dich ruhig durch. Hier in der ng wird Dir sicher jemand weiterhelfen.

Gruß
Werner
-
#include <iostream> using namespace std; int main() { int nPunkte = 0, nNote = 0; cin >> nPunkte; nNote = nPunkte / 3; nNote += nPunkte % 3 == 0 ? 0 : 1; nNote = 6 - nNote; cout << "Note: " << nNote << endl; return 0; }