Parameter Problem. "bezeichner nicht definiert" obwohl in der Klasse vorhanden. -= gelöst =-



  • Hi Leute. Nun bin ich auf ein Problem gestossen was ich mir wieder mal nicht erklären kann.

    #include <iostream>
    #include <string>
    #include <Rechner.h>
    
    using namespace std;
    
    //-------------Übersicht der Parameterreihenfolge-------------------------------------------
    /*
    void AKreis(int r);
    void UKreis(int r2);
    void ADreieck(int hoehe , int g);
    void ARechteck(int a , int b);
    void VZylinder(int hoehe2, int r3);
    void URaute(int a2);					   
    void ARaute(int e , int f);				   
    void AParallelogramm(int g2 , int hoehe3); 
    void ATrapez(int a3 , int c , int hoehe4); 
    void ADrachen(int e2 , int f2);			   
    void VKegel(int r4 , int hoehe5);		  
    void VKugel(int r5);					   
    void VPyramide(int hoehe6 , int a4);	  
    */
    //-----------------------Ende der Übersicht-------------------------------------------------
    
    void main ()
    {
    	Rechner rechner;
    	string s;
    	int wahl;
    	cout << "Bitte waehlen Sie die gewuenschte Option:" << endl;
    	cout << "\n(1) Flaecheninhalt eines Kreises" << endl;
    	cout << "(2) Umfang eines Kreises" << endl;
    	cout << "(3) Flaecheninhalt eines Dreiecks" << endl;
    	cout << "(4) Flaecheninhalt eines Rechtecks" << endl;
    	cout << "(5) Volumen eines Zylinders" << endl;
    	cout << "(6) Umfang einer Raute" << endl;
    	cout << "(7) Flaecheninhalt einer Raute" << endl;
    	cout << "(8) Flaecheninhalt eines Parallelogramms" << endl;
    	cout << "(9) Flaecheninhalt eines Trapezes" << endl;
    	cout << "(10) Flaecheninhalt eines Drachen" << endl;
    	cout << "(11) Volumen eines Kegels" << endl;
    	cout << "(12) Volumen einer Kugel" << endl;
    	cout << "(13) Volumen einer pyramide" << endl;
    	cin >> wahl;
    	if (wahl > 13)
    	{
    		cout << "Bitte geben sie die Zahl ein, die für die Option Ihrer Wahl steht." << endl;
    		cout << "Druecken Sie eine beliebige Taste um zum Menue zu kommen." << endl;
    		cin.get();
    		cout.clear();
    		main ();
    	}
    	if (wahl < 1)
    	{
    		cout << "Bitte geben sie die Zahl ein, die für die Option Ihrer Wahl steht." << endl;
    		cout << "Druecken Sie eine beliebige Taste um zum Menue zu kommen." << endl;
    		cin.get();
    		cout.clear();
    		main ();
    	}
    	if (cin >> s)
    	{
    		cout << "Bitte geben sie die Zahl ein, die für die Option Ihrer Wahl steht." << endl;
    		cout << "Druecken Sie eine beliebige Taste um zum Menue zu kommen." << endl;
    		cin.get();
    		cout.clear();
    		main ();
    	}
    if ( wahl == 1)
    {
    	cout.clear();
    	rechner.AKreis(r);
    }
    if ( wahl == 2)
    {
    	cout.clear();
    	rechner.UKreis(r2);
    }
    

    dieser Quellcode ist natürlich nicht vollständig. da kommt noch was. Aber ich kriege das exception handling hier nicht alleine hin. Der Fehler lautet : "Der Bezeichner r ist nicht definiert."
    und das selbe nochmal mit r2.
    in der Klasse Rechner allerdings habe ich die Elementfunktionen klar deklariert und definiert.

    Hier scheint es ein Problem mit der Parameterübergabe zu geben. Kann mir da wer weiterhelfen ? Wenn nötig, poste ich meine Klasse auch noch hier rein.

    Hier jedenfalls die deklaration:

    void AKreis (int r);
    

    und hier die Definition:

    void Rechner :: AKreis (int r)
    {
    int AKreis;
    cout << "Bitte geben Sie den Radius des Kreises an." << endl;
    cin >> r;
    AKreis = pi*r*r;
    cout << "\nDer Flächeninhalt des Kreises lautet: " << AKreis << " !" << endl;
    }
    

  • Mod

    Zodiac Uchiha schrieb:

    dieser Quellcode ist natürlich nicht vollständig. da kommt noch was. Aber ich kriege das exception handling hier nicht alleine hin. Der Fehler lautet : "Der Bezeichner r ist nicht definiert."
    und das selbe nochmal mit r2.
    in der Klasse Rechner allerdings habe ich die Elementfunktionen klar deklariert und definiert.

    Und? Nur weil irgendwo eine Variable r in einer Funktion existiert, gibt es dadurch nicht ganz woanders den Bezeichner r. Und das ist auch gut so.

    Und main darf man übrigens nicht selber aufrufen, auch wenn es eventuell bei dir ausnahmsweise funktioniert. Und main muss immer int als Rückgabewert haben (man darf jedoch das return weglassen, dann gibt es 0 zurück), das hauen dir auch jede Menge Compiler um die Ohren.

    Und dein Code wird ziemlich sicher nicht das tun, was du willst. Und er ist schrecklich. Deswegen bekommst du keine konkreten Verbesserungsvorschläge außer Lehrbuch wegschmeißen, dann ein gutes Buch besorgen und nochmal neu machen.



  • Und er ist schrecklich. Deswegen bekommst du keine konkreten Verbesserungsvorschläge außer Lehrbuch wegschmeißen, dann ein gutes Buch besorgen und nochmal neu machen.

    Das war schonmal sehr freundlich. Bin mal gespannt ob das hier normal ist.
    Gerade Anfänger haben Hilfe nötig. Und ein solches Forum ist dafür da um sich gegenseitig zu helfen. Und ich habe dieses Forum empfohlen bekommen. Mal sehen wie es weitergeht.

    um aufs Thema zurückzukommen:
    Ich weiss wie die Parameterübergabe ausehen kann. man deklariert eine variable und weist ihr einen Wert hinzu. Dann schreibt man diese Variable als Parameter in die Funktion hinein. Das ist kein Problem. Um mein Problem genauer zu schildern: Ich möchte, dass der User was eingibt und dies dann als Parameter genommen wird.



  • Zodiac Uchiha schrieb:

    man deklariert eine variable und weist ihr einen Wert hinzu..

    So ist das. Jetzt zeig mir mal, wo du in deiner main()-Funktion r deklariert hast.
    Die Hinweise und Tipps von SeppJ solltest du zu Herzen nehmen (auch wenn sie nicht so freundlich rüberkommen, sind sie nett gemeint). Ich gebe nochmal meinen Senf dazu: um die wahl-Überprüfungen und main()-Selbstaufrufe zu vermeiden, verwende Schleifen (while wäre in diesem Fall wahrscheinlich das beste) - die solltest du mittlerweile kennen.



  • Zodiac Uchiha schrieb:

    um aufs Thema zurückzukommen:
    Ich weiss wie die Parameterübergabe ausehen kann. man deklariert eine variable und weist ihr einen Wert hinzu. Dann schreibt man diese Variable als Parameter in die Funktion hinein. Das ist kein Problem. Um mein Problem genauer zu schildern: Ich möchte, dass der User was eingibt und dies dann als Parameter genommen wird.

    Dann mach es doh auch so, wie du das beschrieben hast - du definierst in der main() eine Variable, holst ihren Wert und gibst sie an die Funktion weiter:

    int radius;
    cin >> radius;
    rechner.AKreis(radius);
    

    Ansonsten ein paar Hinweise (ohne Anspruch auf Vollständigkeit):
    * die drei Abfragen für ungültige Eingaben haben die selben Anweisungen und könnten problemlos zusammengefasst werden
    * die letzte Abfrage ( if(cin>>s)... ) ist unsinnig und wird immer erfolgreich sein - außer der Anwender schießt per Ctrl+C die Konsole ab
    * So wie die Funktion momentan aussieht, ist der Parameter sinnlos - entweder du läßt dir die Werte von außen übergeben oder du holst sie von der Konsole (cin). Ich wäre eher für ersteres (und bei der Gelegenheit sollte die Funktion den berechneten Wert auch als Rückgabe rausgeben statt ihn nach cout zu schreiben).
    * bei den Kreisberechnungen wäre es eventuell besser, wenn du mit double-Werten arbeitest
    * cout.clear() ist bestimmt nicht so oft nötig, wie du es verwendest
    * die rekursiven Aufrufe von main() wurden schon erwähnt - verwende da lieber eine normale Schleife, um die Auswahl bei Bedarf zu wiederholen

    * und für eine reine Sammlung von Berechnungsmethoden brauchst du keine Klasse - dafür reicht ein Namensraum völlig aus



  • Jau Nun weiss ich zumindest , dass ich zu kompliziert gedacht habe. Für das was ich vorhabe brauche ich keine parameter habe ich festgestellt. Sondern es reicht wenn ich Variablen deklariere und mit ihnen innerhalb der Funktion hantiere.
    Aber danke schonmal für die ganzen Hinweise.

    Nur jetzt, wo wenigstens schonmal das Programm startet, verstehe ich ein paar sachen nicht.

    1. Du sagtest ja, dass ich cout.clear(); nicht so häufig brauchen werde wie ich es eigentlich verwende. Die Sache ist die : Ich dachte cout.clear(); ist dafür da um die ganzen Sachen in der Konsole zu löschen die bisher dort standen. Halt sodass wieder die ganze Konsole von der ersten Zeile wieder beschrieben werden kann. Um die Übersicht für den User zu bewahren hatte ich vor das zu machen. Also entweder die funktion ist genau dafür da und dieser bestimmte if-Zweig in meinem Code klappt nicht oder ich habe mich einfach nur getäuscht was der Sinn und Zweck von cout.clear(); ist. Wäre super wenn man mir da zur Hand geht.

    2. zwischendurch hat er mir Fehler ausgespukt wo er meinte, dass es Datenverlust bei der konvertierung von double nach int geben kann. bei der Rechner klasse habe ich den radius, höhe usw als int deklariert. Aber das Ding ist, diese Angaben können ja auch Fliesskommazahlen sein. darum habe ich den Datentyp zu double gemacht. Aber so wie ich das verstanden habe , ist double ja nur Datentyp für Fliesskommazahlen und nicht auch für Ganzzahlen. Wie kann ich meinem Programm verständlich machen, dass es beide Zahlentypen lesen und anständig auswerten können soll ?

    Ich denke die Tatsache, dass er im moment die Funktionen nicht ausführt die ich in der Rechnerklasse definiert habe wird wohl nur an meiner üblen if-Zweig geschichte liegen und dem teilweise überflüssigen Kram der da drin steht. Ich werde auf jeden fall dem Vorschlag folgen dort eine While-schleife einzubauen. Auf die weise sag ich ihm einmal was er machen soll und er macht es immer wieder wenn denn die bedingung stimmt. Danke also auch an [Rewind]. Und da ich alles in der Main() nochmal von vorne bis hinten konstruiere, greift dort also auch ein Vorschlag von SeppJ. Danke also auch dafür.



  • 1. Zum leeren der Konsole nimm

    system("Cls");
    

    aus der <cstdlib>.
    Und zu cout.clear() : STFW !! 😃

    2. Ein double hat (natürlich) mindestens 8 byte. Die Höhere Bit-Ebene geht da verloren. Beispiel:

    00101011-10100101-1001101-10110110-10010101-10101101-01010100-01010101
    

    Zu int (auf 32 bit):

    10010101-10101101-01010100-01010101
    
    #include <iostream>
    #include <iomanip>
    
    int main(){
    
    	double a(0);
    	int b(0);
    
    	a=4000000000;
    	b=a;
    
    	std::cout << std::fixed << a << '\n' /// Gibt 4000000000.000000 aus
    	     << b << std::endl;/// Gibt 2147483647 aus
    }
    

    Ideone: https://ideone.com/AVin3#view_edit_box

    Daten gehen verloren. Die Herausgegebene zahl ist undefiniert (oder ist das Compilerspezifisch ?).(Implizite) Typ-Konvertierung ist bei sowas nur sinnvoll, wenn du nicht mit Großen Zahlen rumhantierst. Und dann kannste ja auch float nehmen.

    Double is nicht nur für Fließkommazahlen, sondern auch dafür da.
    Du kannst also genauso z.B. 45678 in einem double, bzw. float abspeichern wie in einem integral.

    Weiter im Programm ...
    Nimm Switch/case abfrage für das zeugs mit dem Menü. Ist viel Praktischer.
    Außerdem kannst du statt

    cout<<"Irgwas"<<endl;
    cout<<"WAsAneres"<<endl;
    

    auch

    cout<<"Irgwas\n"
          "Wasandees"<<endl;
    

    Schreiben. Sieht hübscher aus.
    🕶



  • Hacker schrieb:

    2. Ein double hat (natürlich) mindestens 8 byte.

    So ein Quatsch! Der C++ Standard macht keine solche Garantie.

    Hacker schrieb:

    Die Höhere Bit-Ebene geht da verloren. Beispiel:

    00101011-10100101-1001101-10110110-10010101-10101101-01010100-01010101
    

    Zu int (auf 32 bit):

    10010101-10101101-01010100-01010101
    

    So ein Quatsch! Das, was Du hier zeigst, gilt nur für vorzeichenlose Ganzzahltypen und entspricht der modulo-Regel aus dem C++ Standard.

    #include <iostream>
    #include <iomanip>
    
    int main(){
    	
    	double a(0);
    	int b(0);
    	
    	a=4000000000;
    	b=a;
    	
    	std::cout << std::fixed << a << '\n' /// Gibt 4000000000.000000 aus
    	     << b << std::endl;/// Gibt 2147483647 aus
    }
    

    Du rufst undefiniertes Verhalten hervor. Da könnte alles mögliche rauskommen, oder es könnte abstürzen, oder sonst was.

    Double is nicht nur für Fließkommazahlen, sondern auch dafür da.
    Du kannst also genauso z.B. 45678 in einem double, bzw. float abspeichern wie in einem integral.

    🙄

    Ich weiß, Du wolltest nur helfen. Aber gefährliches Halbwissen ist nicht besonders hilfreich.



  • krümelkacker schrieb:

    So ein Quatsch! Das, was Du hier zeigst, gilt nur für vorzeichenlose Ganzzahltypen und entspricht der modulo-Regel aus dem C++ Standard.

    So sieht es doch natürlich auch nicht 'in echt' aus !

    krümelkacker schrieb:

    Du rufst undefiniertes Verhalten hervor. Da könnte alles mögliche rauskommen, oder es könnte abstürzen, oder sonst was.

    Eben.


  • Mod

    Zodiac Uchiha schrieb:

    1. Du sagtest ja, dass ich cout.clear(); nicht so häufig brauchen werde wie ich es eigentlich verwende. Die Sache ist die : Ich dachte cout.clear(); ist dafür da um die ganzen Sachen in der Konsole zu löschen die bisher dort standen. Halt sodass wieder die ganze Konsole von der ersten Zeile wieder beschrieben werden kann. Um die Übersicht für den User zu bewahren hatte ich vor das zu machen. Also entweder die funktion ist genau dafür da und dieser bestimmte if-Zweig in meinem Code klappt nicht oder ich habe mich einfach nur getäuscht was der Sinn und Zweck von cout.clear(); ist. Wäre super wenn man mir da zur Hand geht.

    Nein, clear macht wirklich was ganz anderes:
    http://www.cplusplus.com/reference/iostream/ios/clear/
    (Die Referenz ist übrigens gut, die solltest du dir merken)
    Konsole löschen geht mit portablen Standardmitteln nicht, da nicht einmal standardisiert ist, dass du auf einer Konsole bist. Die Idee mit dem system("cls"); geht da schon in eine anfängerfreundliche Richtung zur Lösung. Eventuell das cls noch anpassen an deine Konsole (also z.B. clear auf so ziemlich allen nicht-Windows-Konsolen). System ist aber mit vorsicht zu genießen, wenn du es oft brauchst, solltest du dich mittelfristig nach Alternativen, z.B. einer Konsolenbibliothek umsehen.

    2. zwischendurch hat er mir Fehler ausgespukt wo er meinte, dass es Datenverlust bei der konvertierung von double nach int geben kann. bei der Rechner klasse habe ich den radius, höhe usw als int deklariert. Aber das Ding ist, diese Angaben können ja auch Fliesskommazahlen sein. darum habe ich den Datentyp zu double gemacht. Aber so wie ich das verstanden habe , ist double ja nur Datentyp für Fliesskommazahlen und nicht auch für Ganzzahlen. Wie kann ich meinem Programm verständlich machen, dass es beide Zahlentypen lesen und anständig auswerten können soll ?

    double kann auch mit Ganzzahlen umgehen.



  • Jo danke Leute. Ich komme dem Programm( Wie es sein soll) immer näher. Das

    system(cls");
    

    ist wirklich genial. Und die idee mit der Konsolenbibliothek ist auch super. da werd ich mal nach suchen. Solange ich noch das Grundwissen mit den Konsolenanwendungen lerne, lohnt es sich auf jeden fall nach sowas zu suchen. Und die referenz werd ich mir auch merken.

    Also das Fehlerabfangen meiner menügeschichte funktioniert schonmal. d.h. wenn die eingabe ein string ist, wenn die eingabe eine negative zahl ist oder auch wenn die eingabe grösser als 14 ist.
    Nun habe ich die Fälle 1-14 zu definieren. Ich habe den Switch empfohlen bekommen. Jedoch habe ich diesen schon ein paar mal ausprobiert aus interesse ob er echt so praktisch ist und muss auch da ein paar Fragen stellen.
    Es heisst, dass man mit Switch alles machen kann was man auch mit if-else machen könnte. Aber das stimmt doch so nicht oder? weil wenn ich bei case folgendes schreibe...

    int wahl
    cin >> wahl;
    
    switch (wahl)
    {
     case wahl >=2 && wahl <= 4:              // mag er nicht
    cout << "ist nur nen Beispiel"<< endl;
    break;
    }
    

    ...dann sagt er , dass case einen konstanten wert aufweisen muss. aber bei if-else hätte ich das ohne Probleme in den Ausdruck schreiben können. Deswegen hatte ich dem Switch-Zweig fürs erste den Krieg erklärt. Ich kam mit if-else bisher besser zurecht. Evt liegts auch einfach daran , dass ich noch nicht genug wissen habe was den Switch-Zweig angeht und man das anders hätte schreiben müssen.


  • Mod

    Ich glaube, du hast das verdreht: Alles was du mit switch kannst, kannst du auch mit if-then-else machen.

    Ich halte switch ja für ein typisches Konstrukt, an dem man Aufgaben aus Programmierkursen erkennen kann (und Programmierer die gerade frisch aus einem Programmierkurs kommen), denn in freier Wildbahn ist es mir bisher glaube ich erst 1x begegnet.



  • Das er das 'nicht mag', liegt wohl daran, dass case einen Konstanten ausdruck haben muss, bei dir wäre das

    case 2:case 3:case 4:
    

    Switch/case lohnt sich aber überhaupt erst, wenn du mehr als 5,6 Werte hast, die spezifisch zu behandeln sind.



  • Hacker schrieb:

    Switch/case lohnt sich aber überhaupt erst, wenn du mehr als 5,6 Werte hast, die spezifisch zu behandeln sind.

    Nö.



  • Jo ok. Also ich habe mittlerweile den Fall definiert, wenn der user das Programm/die Option 1 auswählt. formel steht für die Konstruierte Klasse "Formeln":

    int wahl;
    cin >> wahl;
    
       switch (wahl)
    {
                     case 1:
    			system("cls");
    			formel.AKreis();
    		cout << "'1' fuer das Hauptmenue oder '0' zum beenden" << endl;
    			int wahl2;
    			cin >> wahl2;
    			while ( wahl2 != 0 || wahl2 != 1 || cin >> s)
    			{
    	cout << "Falsche Eingabe. Sie werden nun zum Hauptmenue geleitet" 
    	        "durch Drücken einer beliebigen Taste." << endl;
    			 _getch();
    			 system("cls");
    			 main();
    			}
    			if ( wahl2 == 1)
    			{
    				system("cls");
    				main();
    			}
    			if ( wahl2 == 0)
    			{
    				exit(1);
    			}
    			break;
    }
    

    Hier nochmal die definierte Elementfunktion ausserhalb der Klasse Formeln aber in der selben Datei der Klasse. So wollte ich es mir sparen eine extra cpp-Datei anzulegen für die Definition der Elementfunktionen.

    void Formeln :: AKreis ()
    {
    	double r;
    	double AKreis;
    	cout << "Bitte geben Sie den Radius des Kreises an." << endl;
    	cin >> r;
    	AKreis = pi*r*r;
    cout << "\nDer Flächeninhalt des Kreises lautet: " << AKreis << " !" << endl;
    }
    

    Ich persönlich kann da keine Fehler entdecken. Der witz ist, der Compiler auch nicht. Wenn man die 1 eingibt, erkennt er zwar die 1 und die steht dann auch da aber die Aktion die ich im case 1 definiert habe passiert einfach nicht. auch mit einem if else nicht. daher gehe ich davon aus , dass die Syntax der switch-anweisung richtig ist , aber der Hacken woanders liegt. habe ich recht?

    Übrigens verwende ich <conio.h> nur für _getch(); weil cin.get(); nicht funktioniert. oder muss ich da etwas spezielles für inkludieren?


  • Mod

    Kannst du da als vollständiges, compilierbares, aber minimales Beispiel, vorzugsweise mit einer lesbaren Einrückung, noch einmal posten?



  • klar :

    #include <iostream>
    #include <string>
    #include <Formeln.h>
    #include <cstdlib>
    #include <conio.h>
    
    using namespace std;
    int prozess();
    
    int main()
    {
    	prozess();
    }
    
    int prozess()
    {
    	Formeln formel;
    	cout << "Hauptauswahl" 
    		 << "\n\nBitte waehlen Sie das gewuenschte Programm:"
    		 << "\n\n(1) Flaecheninhalt eines Kreises" 
    		 << "\n(2) Umfang eines Kreises" 
    		 << "\n(3) Flaecheninhalt eines Dreiecks" 
    		 << "\n(4) Flaecheninhalt eines Rechtecks" 
    		 << "\n(5) Volumen eines Zylinders" 
    		 << "\n(6) Umfang einer Raute" 
    		 << "\n(7) Flaecheninhalt einer Raute" 
    		 << "\n(8) Flaecheninhalt eines Parallelogramms" 
    		 << "\n(9) Flaecheninhalt eines Trapezes" 
    		 << "\n(10) Flaecheninhalt eines Drachen" 
    		 << "\n(11) Volumen eines Kegels" 
    		 << "\n(12) Volumen einer Kugel" 
    		 << "\n(13) Volumen einer pyramide" 
    		 << "\n(14) Programm beenden" << endl;
    	int wahl;
    	cin >> wahl;
    	if (wahl == 14)
    	{
    		exit(1);
    	}
    	if (wahl > 14)
    	{
    		cout << "fehler weil wegen grösser" << endl;
    		_getch();
    		system("cls");
    		prozess();
    	}
    	if (wahl < 1)
    	{
    		cout << "fehler weil wegen kleiner" << endl;
    		_getch();
    		system("cls");
    		prozess();
    	}
    	if ( !wahl )
    	{
    	        cin.clear();
    		string h;
    		getline (cin , h);
    		cout << "keine zeichen bitte."
    			 << "\nZurueck zur hauptauswahl." << endl;
    		_getch();
    		system("cls");
    		prozess();
    	}
    	else
    	{
    	 	if (wahl == 1)
    		{
    			system("cls");
    			formel.AKreis();
    			cout << "Ende des Programms. Zur Hauptauswahl?"
    				 << "\n(1)Ja"
    				 << "\n(2)beenden" << endl;
    			int wahl2;
    			cin >> wahl2;
    			if ( wahl2 == 1)
    			{
    				system("cls");
    				prozess();
    			}
    			if ( wahl2 == 2)
    			{
    				exit(1);
    			}
    			if ( wahl2 > 2)
    			{
    				system("cls");
    cout << "Zu grosse Zahl. Bitte die richtigen zahlen eingeben."
     << "\nSie werden nach druecken einer beliebigen Taste zur Hauptauswahl geleitet."; 
    				_getch();
    				system("cls");
    				prozess();
    			}
    			if ( wahl2 < 1)
    			{
    				system("cls");
    cout << "Negative Zahlen oder '0' sind eine falsche Eingabe!" 
    << "\nBitte nur die geforderten Zahlen eingeben."
    << "Sie werden durch druecken einer beliebigen Taste zur Hauptauswahl geleitet." <<endl;
    				_getch();
    				system("cls");
    						prozess();
    			}
    			else
    			{
    				system("cls");
    				cin.clear();
    				string s;
    				getline(cin , s);
    cout << "Zeichen sind nicht erlaubt. Bitte nur die geforderten zahlen eingeben."
    << "Sie werden durch druecken einer beliebigen Taste zur Hauptauswahl geleitet." << endl;
    				_getch();
    				system("cls");
    				prozess();
    			}
    		}
    	}
    }
    

    hierbei habe ich die anderen Fälle 2 - 13 ausgelassen weil das einfach zu lang gewesen wäre. Aber nach dem Schema würde ich weiter vorgehen.
    bei dem if ( !wahl ) habe ich versucht strings abzufangen. funktioniert aber nicht.
    der fall if ( wahl == 1 ) funktioniert
    der fall if ( wahl == 14) auch
    und die beiden Abfänger auch.
    Mittlerweile komme ich also nur noch mit denm abfangen von strings nicht klar.

    hab versucht so lesbar wie möglich zu bleiben aber die zeilen mit cout die zu lang sind denkt man sich dann einfach in der richtigen Zeile



  • Mit der Bedingung "if(!wahl)" fängst du nur die Eingabe 0 ab, bei nichtnumerischen Eingaben würde sich schon der Input-Operator querstellen, das bekommst du per "if(!cin)" am besten mit.

    PS: Deine Rekursions-Lösung könnte problematisch sein bei längerer Arbeit mit dem Programm - verwende lieber eine Schleife (und switch() für die Fall-Unterscheidungen).



  • okay das mit der 0 eingabe habe ich verstanden weil

    !wahl
    

    equivalent zu

    wahl = 0
    

    ist.

    das mit den switch statt die ganzen ifs habe ich auch verstanden. aber

    PS: Deine Rekursions-Lösung könnte problematisch sein bei längerer Arbeit mit dem Programm

    verstehe ich nicht ganz. warum ist das mit den ganzen ifs problematisch ?

    und

    verwende lieber eine Schleife (und switch() für die Fall-Unterscheidungen).

    verstehe ich nur teilweise weil : ich soll switch statt ifs nehmen. aber du hast davor schleife erwähnt. das verstehe ich nicht ganz.



  • Zodiac Uchiha schrieb:

    PS: Deine Rekursions-Lösung könnte problematisch sein bei längerer Arbeit mit dem Programm

    verstehe ich nicht ganz. warum ist das mit den ganzen ifs problematisch ?

    Mit der Rekursion meinte ich nicht die if's als solche, sondern die Tatsache, daß du am Ende jedes if-Zweigs (außer if(wahl==14) ) die Funktion wieder selber aufrufst. Damit füllst du auf lange Sicht nur den Stack, bis dein Programm irgendwann nicht genug Speicher für den nächsten Aufruf von process() hat. Statt dieser Konstruktion ist eine Schleife besser ala:

    bool ende = false;
    while(!ende)
    {
      ...
      switch(wahl)
      {
        ...
        case 14:
          ende=true;
          break;
        ...
      }
      ...
    }
    


  • aaach nun weiss ich glaube ich worum es geht. Weil ich die methode selber immer wieder aufrufe, hämmert das immer wieder den Speicher zu und ist dann irgendwann voll. und daher nimmt man die while schleife weil man so etwas wiederholen lassen kann ohne den speicher zu verbrauchen.

    nur nun kommen mir einige Fragen..
    wenn ich switch nutze, und beim case eingebe:

    case > 14:
    

    dann sagt er mir, dass er einen konstanten Ausdruck erwartet. Daher werde ich die Fehler wohl mit ifs abfangen müssen oder?

    und wenn ich das richtig verstanden habe, muss ich ende gleich true setzen wenn ich alle abfragen fertig habe also dann nach ganz unten. erst dann erkennt er das ende oder?
    also so :

    bool ende = false ;
    while (!ende)
    {
      abfrage wahl = 1
      ...
      abfrage wahl = 14
      abfrage der zahlen kleiner 0
      abfrage der zahl 0
      abfrage der zahlen grösser 14  ende = true
    }
    

    korrekt ?
    was ich ja vorhabe ist, nach jedem fall ( 1- 13 ) soll der nutzer auch wieder zur hauptauswahl zurück kommen können. das ist der einzige grund warum ich die methode hab wiederholen lassen. wie mache ich das denn ohne den speicher voll zu stapeln?
    Kann man nicht per Variable einen Standpunkt festlegen der dann später aufgerufen werden kann, sodass das programm ab dem Punkt fortgesetzt wird?


Anmelden zum Antworten