Buchstabeneingabe Verbieten



  • Hallo leute, ich hab kürzlich angefangen mich in c++ einzulesen mit dem Buch "Jetzt lerne ich c++" ich habe schon mein erstes kleines Programm geschrieben, einen Taschenrechner der mal rechnet, wenn statt einer Zahl allerdings einen Buchstaben eingibt spinnt das programm komplett rum, wie kann ich die Eingabe von Buchstaben verbieten? für befehle die nicht in meinem code stehen wäre es nett wenn ihr ne kurze erklärung abgebt was das macht 😃

    Hier mein code:

    #include <iostream>
    using namespace std;
    int main()
    {	// start
    	double zahl1, zahl2, ergebnis;
    
    	//Rechnung:;
    
    	//Erste Zahl
    
    	cout << endl;
    	cout << " Geben Sie die erste Zahl ein: ";
    	cin >> zahl1;
    
    	//Zweite Zahl
    
    	cout << " Geben Sie die zweite Zahl ein: ";
    	cin >> zahl2;
    	} else 
    
    	ergebnis = zahl1 * zahl2;
    	cout << endl;
    	cout << " " << zahl1 << " * " << zahl2;
    	cout << " = " << ergebnis << endl;
    
    	goto Rechnung;
    
    }
    

    edit Jester: code tags eingefügt



  • #include <iostream>
    using namespace std;
    int main()
    {
    	double zahl1, zahl2, ergebnis;
    
    	Rechnung:;
    
    	cout << endl;
    	cout << " Geben Sie die erste Zahl ein: ";
    	cin >> zahl1;
    
    	cout << " Geben Sie die zweite Zahl ein: ";
    	cin >> zahl2;
    	ergebnis = zahl1 * zahl2;
    	cout << endl;
    	cout << " " << zahl1 << " * " << zahl2;
    	cout << " = " << ergebnis << endl;
    
    	goto Rechnung;
    
    }
    

    edit Jester: code tags eingefügt



  • Solange du goto ,das falsche Unterforum und keine Code-Tags benutzt, wäre es für dich einfacher, keine Buchstaben einzutippen.

    Du musst die falschen Zeichen einlesen und den Fehlerzustand des Eingabestroms zurück setzen.
    Z.B.: https://www.c-plusplus.net/forum/244722-full



  • und dann hätte ich noch die frage wie ich rechenzichen eingeben lassen kann



  • Dieser Thread wurde von Moderator/in Jester aus dem Forum Mathematik und Physik in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • nicopro98 schrieb:

    und dann hätte ich noch die frage wie ich rechenzichen eingeben lassen kann

    Als Zeichen.
    Der Variablentyp für ein Zeichen ist char .

    Aber such mal im Forum nach Taschenrechner. Da sollte einiges zu finden sein.
    https://www.c-plusplus.net/forum/search



  • DirkB schrieb:

    Solange du goto ,das falsche Unterforum und keine Code-Tags benutzt, wäre es für dich einfacher, keine Buchstaben einzutippen.

    Du musst die falschen Zeichen einlesen und den Fehlerzustand des Eingabestroms zurück setzen.
    Z.B.: https://www.c-plusplus.net/forum/244722-full

    Ich bin da grad noch am lernen, deswegen hab ich davon auch noch nicht so vie ahnung und kann nur das was da drin is...



  • dann solltest du dich für den moment nicht mit falschen eingaben aufhalten (das thema ist zu kompliziert) sondern erst einmal weiterlesen und mehr basis-konzepte lernen.

    was äußerst wichtig ist:
    verzichte auf goto!
    wenn dir das dein buch so beigebracht hat, schmeiß das buch weg! schreib eine furchtbare rezension darüber und stelle sicher, dass sie gelesen wird.

    wenn du das mit "goto" irgendwo anders im internet aufgeschnappt hast, lösche alle eine lesezeichen dorthin. hacke die seite und lösche sie!

    wenn dir das "goto" ein freund empfohlen hat, kündige die freundschaft. verhindere, dass dein freund jemals wieder einen computer zu gesicht bekommt.



  • scheint ja nicht sehr beliebt zu sein 😃 was ist denn eigentlich das Problem damit? in anderen programiersprachen ist das ja super

    was soll ich denn sonst nutzen um zum anfang zurückzukommen?



  • #include <iostream>
    using namespace std;
    int main()
    {
    	double zahl1, zahl2, ergebnis;
    	char rechenzeichen;
    
    	Rechnung:;
    
    	cout <<" geben sie eine Rechenaufgabe ein ";
    	cin >> zahl1 >> rechenzeichen >> zahl2;
    	switch (rechenzeichen)
    	{
    	case '+': ergebnis = zahl1 + zahl2; break;
    	case '-': ergebnis = zahl1 - zahl2; break;
    	case '*': ergebnis = zahl1 * zahl2; break;
    	case '/': ergebnis = zahl1 / zahl2; break;
    	default: cout << "unbekantes Rechenzeiche...\n"; return 1;
    	}
    	cout << zahl1 << ' ' << rechenzeichen << ' ' << zahl2 << " = " << ergebnis << '\n';
    
    }
    

    jetzt kann er alle rechenarten 😃



  • nicopro98 schrieb:

    was soll ich denn sonst nutzen um zum anfang zurückzukommen?

    Das Zauberwort heißt "Schleife"



  • nicopro98 schrieb:

    scheint ja nicht sehr beliebt zu sein 😃 was ist denn eigentlich das Problem damit? in anderen programiersprachen ist das ja super

    was soll ich denn sonst nutzen um zum anfang zurückzukommen?

    Goto ist in allen höheren Programmiersprachen verpönt.
    Selbst im Basic vom C-64 mochte das Niemand

    Das Problem ist, dass du munter kreuz und quer springen kannst. Das gibt undurschaubaren Spagetticode.



  • DirkB schrieb:

    Selbst im Basic vom C-64 mochte das Niemand

    Das ist so ein wenig zu allgemein.
    Man hat es nicht allgemein abgelehnt.

    Mangels else/break/continue war es zunächst mal notwendig.

    Und es war auch nicht schlecht und es ist nicht schlecht. Ich plane sehr gerne *mit* Verwendung von goto, tippe sogar Code *mit* goto ein. Danach optimiere ich das goto weg. Das klappt immer. Aber mich darauf zu beschränken, ohne goto zu planen, würde mich 30% oder so meiner Effizienz kosten.

    Zurück zum 64-er. Profis ersezten

    …
    15420 gosub 23420
    15430 return
    …
    

    gerne durch

    …
    15420 goto 23420
    …
    

    . Es ist ja garantiert, daß es das selbe macht, aber ein wenig schneller ist. Damals hatte man keinen evtl. ungenau spezifizierten Standard, sondern ganz schlicht die undokumentierte Referenzimplementierung.
    Ok, der Trick war nur ein wenig schneller. Klarer Fall von "goto würden wir heute echt ablehnen", weil selbst der dümmste Compiler das auch oder besser kann. Aber es war damals gut, das Muster kannte jeder. Es hat beim Lesen nicht gestört.

    Krasser ist schon das Vermeiden von goto, wenns inhaltlich eine do-Schleife mit wenig Körper ist oder das Programm groß ist. Die ist ja an sich eine

    …
    15410 rem berechnewas
    …
    16420 if … goto 15410
    …
    

    wird zu

    15409 for a=1 to 2 step 0
    15410 rem berechnewas
    …
    16420 if … next
    16421 a=2
    16422 next
    …
    

    Zweck der Geschichte? Nuja, auf dem 64-er ware goto so implemetiert, daß es zur Laufzeit den Quellcode von vorn bis hinten liest (kleine Optimierung, jede Quellcodezeile hat am Anfang ihr Länge gespeicher, dadurch kann man Zeilenweise hoppeln) und so linear die Zeilennummer sucht, die angesprungen werden dann und dann den Interpreter dort aufsetzt. "next" hingegen springt schicht zur Position nach dem "for", also O(1) gegen O(n) bei n=Codezeilen im Programm.

    Also ja, goto zu vermeiden war gar keine so doofe Idee.

    Alle Unterprograme an den Anfang schieben und die main() und deren Kinder ganz nach unten.

    DirkB schrieb:

    Das Problem ist, dass du munter kreuz und quer springen kannst. Das gibt undurschaubaren Spagetticode.

    Tja, da gehe ich gar nicht mit.



  • volkard schrieb:

    Und es war auch nicht schlecht und es ist nicht schlecht.

    um was zu tun? zu programmieren? mag sein.
    um C++ zu lernen ist es grottenschlecht, und das ist der kontext.

    Ich plane sehr gerne *mit* Verwendung von goto, tippe sogar Code *mit* goto ein. Danach optimiere ich das goto weg. Das klappt immer. Aber mich darauf zu beschränken, ohne goto zu planen, würde mich 30% oder so meiner Effizienz kosten.

    du bist auch ein volkard. ein alexandrescu, der mit makros wild um sich wirft, wird auch niemand ein vorwurf machen.

    aber ich behaupte, nicht ganz gewagt, dass jemand, der heutzutage C++ lernt schneller und besser C++ lernt, wenn er nicht zuerst lernt, was in C üblich ist (war) (oder noch weiter davor).

    nur, weil es möglich ist, gutes C++ zu schreiben, wenn man vorher C gelernt hat (lies: printf, zeiger, malloc/new/delete, operatorenrangfolgen, eingebaute typen, c-strings, built-in-arrays, makros ... und auch goto), heißt das nicht, dass das nötig ist - und schon gar nicht, dass das effektiv ist. was nicht heißt, dass alles, was ich in der klammer aufgezählt habe, "prinziell" unnötig ist.



  • ich habe heute mal ein neues Programm geschrieben dass eigentlichvon grund auf beser funktioniert und aussieht, der fehler mit den buchstaben ist hier auch nicht mehr vorhanden...

    edit: ich weis der code is ziemlich lang aber es funktioniert super!

    #include <iostream>
    using namespace std;
    int main()
    {
    	char eingabe;
    
    	do
    	{
    		cout << "Hauptmenu\n Was fuer eine Rachnung wollen sie durchführen? " << endl;
    		cout << " +			<1> " << endl;
    		cout << " -			<2> " << endl;
    		cout << " *			<3> " << endl;
    		cout << " /			<4> " << endl;
    		cout << " Beenden	<5> " << endl;
    		cout << endl;
    		cout << " Ihre Eingabe: ";
    		cin >> eingabe;
    		cout << endl;
    
    		switch (eingabe)
    
    		{
    
    		case '1':
    			double zahl1, zahl2, ergebnis;
    			cout << endl;
    			cout << "geben sie die erste Zahl ein:\n ";
    			cin >> zahl1;
    			cout << "geben sie die zweite zahl ein:\n ";
    			cin >> zahl2;
    
    			ergebnis = zahl1 + zahl2 ;
    			cout << endl;
    			cout << " " << zahl1 << " + " << zahl2;
    			cout << " = " << ergebnis << endl;
    			cout << endl;
    			break;
    		case '2':
    			double zahl3, zahl4, ergebnis2;
    
    			cout << endl;
    			cout << "geben sie die erste Zahl ein:\n ";
    			cin >> zahl3;
    			cout << "geben sie die zweite zahl ein:\n ";
    			cin >> zahl4;
    
    			ergebnis2 = zahl3 - zahl4 ;
    
    			cout << endl;
    			cout << " " << zahl3 << " - " << zahl4;
    			cout << " = " << ergebnis2 << endl;
    			cout << endl;
    			break;
    
    		case '3':
    
    			double zahl5, zahl6, ergebnis3;
    
    			cout << endl;
    
    			cout << "geben sie die erste Zahl ein:\n ";
    			cin >> zahl5;
    			cout << "geben sie die zweite zahl ein:\n ";
    			cin >> zahl6;
    			ergebnis3 = zahl5 * zahl6 ;
    			cout << endl;
    			cout << " " << zahl5 << " * " << zahl6;
    			cout << " = " << ergebnis3 << endl;
    			cout << endl;
    			break;
    		case '4':
    			double zahl7, zahl8, ergebnis4;
    			cout << endl;
    			cout << "geben sie die erste Zahl ein:\n ";
    			cin >> zahl7;
    			cout << "geben sie die zweite zahl ein:\n ";
    			cin >> zahl8;
    
    			ergebnis4 = zahl7 / zahl8 ;
    			cout << endl;
    			cout << " " << zahl7 << " / " << zahl8;
    			cout << " = " << ergebnis4 << endl;
    			cout << endl;
    			break;
    		case '5': cout << " Programm wird beendet " << endl;
    			break;
    		default: cout << " Ungueltige Eingabe! " << endl;
    		}
    
    		cout << endl;
    	} while ( eingabe != '5');
    
    	return 0;
    	}
    


  • Alle Zeilen die mehrfach vorkommen, kannst du vor oder nach dem switch schreiben.
    Überleg mal, ob du wirklich 8 Zahlen und 4 Ergebnisse brauchst.

    Da bei dir eingabe ein char ist, bist du nicht auf Ziffern beschränkt. '+', '-', '*' und '/' geteilt gehen da auch.



  • DirkB schrieb:

    Da bei dir eingabe ein char ist, bist du nicht auf Ziffern beschränkt. '+', '-', '*' und '/' geteilt gehen da auch.

    ja aber dann sagt der ja dass die eingabe ungültig ist, ist also kein problem, wenn du mir nen tipp geben könntest wie ich zahl1 , zahl2 und ergebnis in jedem case verwenden kann wäre das gut, wenn ich die nämlich für jeden einfach eingebe spuckt der compiler mir ne fehlermeldung aus: Fehler 1 error C2086: 'double zahl1': Neudefinition



  • nicopro98 schrieb:

    Da aber dann sagt der ja dass die eingabe ungültig ist, ist also kein problem,

    Du musst natürlich einen case dafür anlegen.
    Man kann auch einen Block für mehrere case nehmen.
    https://de.wikibooks.org/wiki/C-Programmierung:_Kontrollstrukturen#switch

    switch (eingabe)
            {
            case '+':  // da hier kein break steht, wird der nachfolgende Code ausgeführt.
            case '1':
                ergebnis = zahl1 + zahl2 ;
                break;
    ,,,
    

    nicopro98 schrieb:

    wenn du mir nen tipp geben könntest wie ich zahl1 , zahl2 und ergebnis in jedem case verwenden kann wäre das gut, wenn ich die nämlich für jeden einfach eingebe spuckt der compiler mir ne fehlermeldung aus: Fehler 1 error C2086: 'double zahl1': Neudefinition

    Du musst die Variablen eben einmal davor definieren.



  • #include <iostream>
    #include <cmath>
    using namespace std;
    int main()
    {
    	char eingabe;
    
    	do
    	{
    		cout << "Hauptmenu\n Was fuer eine Rechnung wollen sie durchfuehren? " << endl;
    
    		// Eingabemöglichkeiten
    		cout << "Funktionen:    |    Ihre eingabe: \n";
    		cout << "_____________________________\n_____________________________\n" << endl;
    
    		cout << "  +			<1> " << endl;
    		cout << "_____________________________\n" << endl;
    		cout << "  -			<2> " << endl;
    		cout << "_____________________________\n" << endl;
    		cout << "  *			<3> " << endl;
    		cout << "_____________________________\n" << endl;
    		cout << "  /			<4> " << endl;
    		cout << "_____________________________\n_____________________________" << endl;
    		cout << "Verlassen				<5> " << endl;
    
    		cout << endl;
    		cout << " Ihre Eingabe: ";
    		cin >> eingabe;
    		cout << endl;
    
    		while ( eingabe != '5');
    		{
    			return 0;
    		}
    
    		double zahl1, zahl2, ergebnis;
    
    		cout << endl;
    			cout << "geben sie die erste Zahl ein:\n ";
    			cin >> zahl1;
    			cout << "geben sie die zweite zahl ein:\n ";
    			cin >> zahl2;
    
    			ergebnis = zahl1 + zahl2 ;
    
    		// Auswertung der Eingabe
    
    		switch (eingabe)
    
    		{
    			// Addition
    
    		case '1':
    
    			ergebnis = zahl1 + zahl2 ;
    			cout << endl;
    			cout << " " << zahl1 << " + " << zahl2;
    			cout << " = " << ergebnis << endl;
    			cout << endl;
    			break;
    
    			// Subtraktion
    
    		case '2':
    
    			ergebnis = zahl1 - zahl2 ;
    
    			cout << endl;
    			cout << " " << zahl1 << " - " << zahl2;
    			cout << " = " << ergebnis << endl;
    			cout << endl;
    			break;
    
    			// Multiplikation
    
    		case '3':
    
    			ergebnis = zahl1 * zahl2 ;
    			cout << endl;
    			cout << " " << zahl1 << " * " << zahl2;
    			cout << " = " << ergebnis << endl;
    			cout << endl;
    			break;
    
    			// Division
    
    			case '4':
    
    			ergebnis = zahl1 / zahl2 ;
    			cout << endl;
    			cout << " " << zahl1 << " / " << zahl2;
    			cout << " = " << ergebnis << endl;
    			cout << endl;
    			break;
    		case '5': cout << " Programm wird beendet " << endl;
    			break;
    		default: cout << " Ungueltige Eingabe! " << endl;
    		}
    
    		cout << endl;
    	}
    

    da is iwo ein fehler drin



  • Deine while-Schleife ist sehr, sehr merkwürdig.

    Eine Endlosschleife für Werte != '5'.
    Wenn die nicht läuft, kommt das return und das Programm wird verlassen.

    Du suchst eine do-while -Schleife.
    Oder das return im case '5'

    Edit: Durch den Block nach dem while und die Einrückung habe ich das do übersehen.


Log in to reply