Ungewollte Endlosschleife



  • Hallo.
    Habe ein Menü zur Auswahl von gewissen Funktionen. gibt man statt einer zahl jedoch einen Buchstaben/ ein Zeichen ein, wird das Menü unendlich oft durchgeschleust. Die int Variable der Auswahl bleibt anscheinend immer die selbe, oder zumindest fehlerhaft. Auswahl = NULL; sowohl auch Auswahl = 0 haben nicht geholfen.
    Mit delete &vAuswahl kriegt das Programm einen Hänger.
    Hier mal der Code (Nicht wunder, Auswahl heisst glaube ich Kommando)

    int main()
    {
    	Eingang();
    	do
    	{
    	Kommando = 0;
    	Kommando = Menü();						// Auswahlmöglichkeiten
    	Auswahl(Kommando);				//Switch Case
    	}while(Kommando != 10);				// 10 = Beenden
    
    return 0;
    }
    
    int Menü()
    {
    	int Kommando;
    
    	Kommando = 0;
    	cout
    		<<"[1]"	<<setw(7)	<<"Glücksspiel \n"
    		<<"[2]"	<<setw(7)	<<"Wortspiel \n"
    		<<"[3]" <<setw(7)	<<"Bitgrößen von Variabeln \n"
    		<<"[4]" <<setw(7)	<<"Referenzen & Zeiger \n"
    		<<"[10]" <<setw(7)	<<"Ende \n"
    		<<"Ihre Auswahl:";
    	cin
    		>>Kommando;
    
    	return (Kommando);
    
    }
    
    void Auswahl(int &vAuswahl)
    {
    	switch (Kommando)
    	{
    		case 1:
    
    			Glückszahl();
    			break;
    
    		case 2:
    			Wortspiel();
    			break;
    		case 3:
    			SizeOf();
    			break;
    		case 4:
    			ref();
    			break;
    
    		default:
    			{cout
    				<<"Keine gültige Eingabe!"
    				<<endl;
    			vAuswahl=0;
    			delete &vAuswahl;
    			break;
    			}
    	}
    
    }
    


  • Und wo ist Kommando in der main deklariert? Nirgends. Namen mit Umlauten sind keine gute Idee 😉



  • Ne, die ist in der Headerdatei deklariert. Keine gute Idee, nein? 😞



  • Hänselchen schrieb:

    Ne, die ist in der Headerdatei deklariert. Keine gute Idee, nein? 😞

    Globale Variablen sind keine tolle Sache :p vorallem weil du es in einer Funktion lokal nochmals überschreibst.

    delete &vAuswahl;
    

    Das entfernen weil die variable nicht mit new erstellt wurde...



  • Hm, meine headerdate sieht so aus:

    #include <iostream>
    #include <iomanip>
    #include <conio.h>
    #include <string>
    
    using namespace std;
    
    // Variablen //
    
    // FUNKTIONEN //
    
    	int Menü();
    	void Auswahl(int &vAuswahl);
    	void Glückszahl();
    	void Wortspiel();
    	void SizeOf();
    	void Eingang();
    	void Klassen();
    	void Indexoperatoren();
    	void ref();
    

    Ich fand die Main so überlaufen, wenn da so tausende Funktionen stehen... Aber dann sind die ja alle global, oder?

    Und zum Problem an sich: Und wie lautet die lösung? :>



  • Wie wäre es mit anderen Dateien?

    main.cpp
    gluecksspiel.cpp
    gluecksspiel.h
    wortspiel.cpp
    wortspiel.h
    sonstiges.cpp
    sonstiges.h
    ...

    Aber da musst du noch ein wenig nachholen bei deinen Grundlagen. Fang erstmal an Parameterübergaben zu nutzen.



  • du musst den eingabepuffer löschen

    guckst du mal in die faq

    geht irgendwie mit cin.clear und noch was...



  • Problem ist, ich weiss nie WIE ich üben soll...

    Ich habe zwar zu Mass gute Bücher doch ich arbeite lieber praktisch und hab auch gerne Programme, in denen ich das gelesene ausprobieren kann.

    Kennt ihr vielleicht ein geeignetes Projekt, in dem ich sowas üben könnte, oder allgemein Tipps dazu? Weil ehrlich gesagt, weiss ich nie was und wie ich lernen soll...

    Grüße



  • Angenommen der Benutzer gibt in Menü() eine 10 ein, um das Programm zu beenden, dann steht in der globalen(?) Kommando eine 10, da du dieser den Rückgabewert von Menü() zuweist. Danach rufst du Auswahl(...) auf und übergibst die Variable Kommando per Referenz(!). D. h. vAuswahl ist dann eine Referenz auf Kommando. In deinem switch setzt du vAuswahl auf 0, da keiner deiner Zweige zutrifft (vAuswahl == Kommando == 10), dadurch wird auch Kommando auf 0 gesetzt und die Bedingung Kommando != 10 in deiner do-while-Schleife bleibt true, sodass sie weiter läuft.



  • So sollte es besser gehen (ungetestet):

    int main()
    {
        Eingang();
    	int Kommando = 0;
        do
        {
    		Kommando = Menue();		// Auswahlmöglichkeiten
    		Auswahl(Kommando);		// Switch Case
        } while(Kommando != 10); 	// 10 = Beenden
    }
    
    int Menue()
    {
        int Kommando = 0;
        cout
            <<"[1]" <<setw(7) <<"Glücksspiel \n"
            <<"[2]" <<setw(7) <<"Wortspiel \n"
            <<"[3]" <<setw(7) <<"Bitgrößen von Variabeln \n"
            <<"[4]" <<setw(7) <<"Referenzen & Zeiger \n"
            <<"[10]" <<setw(7) <<"Ende \n"
            <<"Ihre Auswahl:";
        cin
            >>Kommando;
    
        return Kommando;
    }
    
    void Auswahl(int Kommando)
    {
        switch (Kommando)
        {
            case 1:
                Glueckszahl();
                break;
            case 2:
                Wortspiel();
                break;
            case 3:
                SizeOf();
                break;
            case 4:
                ref();
                break;
            default:	// Tritt auch bei Kommando==10 (Beenden) ein!
                cout<<"Keine gültige Eingabe!"<<endl;
                break;
        }
    }
    

    Beachte: Es gibt hier drei Variablen mit dem Namen Kommando. Die erste ist lokal in der Funktion main() und ihr wird der Rückgabewert von Menue() zugewiesen. Die zweite ist lokal in Menue(), wird vom Benutzer belegt und dann wird ihr Inhalt als Rückgabewert von Menue() benutzt. Die dritte ist lokaler Parameter von Auswahl(...). In sie wird der Wert der lokalen Kommando-Variable von main() beim Aufruf in main() kopiert.



  • Hänselchen schrieb:

    Hallo.
    Habe ein Menü zur Auswahl von gewissen Funktionen. gibt man statt einer zahl jedoch einen Buchstaben/ ein Zeichen ein, wird das Menü unendlich oft durchgeschleust.

    also das ist eigentlich deine frag, oder nicht?!?

    und genau das problem löst man durch folgendes konstrukt

    std::cin.clear();
    std::cin.ignore(std::cin.rdbuf()->in_avail());
    // std::cin.get(); // für warten dazusetzen, also um z.b. die console vor dem schliessen bewahren
    

    und dies schreibst du am besten hinter jede eingabe (ist aber am langsamsten, wobei hier eh der benutzer der langsamste punkt ist, womit das hier nichts ausmachen dürfte)


Anmelden zum Antworten