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;
    }
    

    😃


Anmelden zum Antworten