Wechselgeld Algorithmus Hilfe



  • Hallo zusammen,

    ich komme bei einer Übungsaufgabe nicht weiter und hoffe ihr könnt mir helfen.
    Ich soll ein Programm in C schreiben welches das Wechselgeld in Form von möglichst großen Münzen ausgibt. Das Programm funktioniert soweit. Die Anzahl der Euro Münzen gibt es richtig aus, jedoch komme ich bei den Cents nicht weiter und verstehe nicht wieso das so wie ich es mir vorstelle nicht funktioniert.

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <Windows.h>
    #include <string.h>
    
    int main()
    {
    	unsigned int auswahlPreisstufe, auswahlTicket;
    	float preis, geld, rest, rueckgeld;
    	int muenzenEuro[] = { 2, 1 };
    	int anzahlEuro;
    
    	char c;
    
    	while (1)
    	{
    		SetConsoleTitle("Wechselgeldautomat");
    		do
    		{
    			printf("Waehlen Sie eine der folgenden Preisstufen aus:\n");
    			printf("(1) Kurzstrecke: 1,20 EURO\n");
    			printf("(2) Preisstufe A: 2,30 EURO\n");
    			printf("(3) Preisstufe B: 3,50 EURO\n\n");
    			printf("Ihre Auswahl: ");
    			scanf_s("\n%d", &auswahlPreisstufe);
    
    			switch (auswahlPreisstufe)
    			{
    			case 1: printf("Sie haben sich fuer: '(1) Kurzstrecke: 1,20 EURO' entschieden.\n\n"); break;
    			case 2: printf("Sie haben sich fuer: '(2) Preisstufe A: 2,30 EURO' entschieden.\n\n"); break;
    			case 3: printf("Sie haben sich fuer: '(3) Preisstufe B: 3,50 EURO' entschieden.\n\n"); break;
    			default: printf("Eingabe ungueltig! Bitte wiederholen\n\n"); break;
    			}
    		} while (auswahlPreisstufe < 1 || auswahlPreisstufe > 3);
    
    		do
    		{
    			printf("Waehlen Sie nun zwischen den beiden Tickets:\n");
    			printf("(1) EinzelTicket\n");
    			printf("(2) 4erTicket\n\n");
    			printf("Ihre Auswahl: ");
    			scanf_s("\n%d", &auswahlTicket);
    
    			switch (auswahlTicket)
    			{
    			case 1: printf("Sie haben sich fuer: '(1) EinzelTicket' entschieden.\n\n"); break;
    			case 2: printf("Sie haben sich fuer: '(2) 4erTicket' entschieden.\n\n"); break;
    			default: printf("Eingabe ungueltig! Bitte wiederholen\n\n"); break;
    			}
    		} while (auswahlTicket < 1 || auswahlTicket > 2);
    
    		do
    		{
    			if (auswahlPreisstufe == 1 && auswahlTicket == 1)
    			{
    				preis = 1.20;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 2 && auswahlTicket == 1)
    			{
    				preis = 2.30;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 3 && auswahlTicket == 1)
    			{
    				preis = 3.50;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 1 && auswahlTicket == 2)
    			{
    				preis = 1.20 * (float)4;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 2 && auswahlTicket == 2)
    			{
    				preis = 2.30 * (float)4;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 3 && auswahlTicket == 2)
    			{
    				preis = 3.50 * (float)4;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			break;
    		} while (preis);
    
    		do
    		{
    			printf("Werfen Sie bitte das Geld ein: ");
    			scanf_s("%f", &geld);
    
    			if (geld == preis)
    			{
    				printf("Vielen Dank! Entnehmen Sie bitte Ihr Ticket.\n\n");
    				break;
    			}
    			if (geld > preis && geld < 21)
    			{
    				printf("Vielen Dank! Entnehmen Sie bitte Ihr Ticket und Ihr Rueckgeld.\n\n");
    				rueckgeld = geld - preis;
    				printf("Rueckgeld: %.2f\n\n", rueckgeld);
    				/////////////////////////////
    				for (int i = 0; i < (sizeof(muenzenEuro) / sizeof(muenzenEuro[i])); i++)
    				{
    					anzahlEuro = rueckgeld / muenzenEuro[i];
    					if (anzahlEuro > 0)
    					{
    						rueckgeld = rueckgeld - anzahlEuro * muenzenEuro[i];
    						printf("%d x %d EURO Muenze(n)\n", anzahlEuro, muenzenEuro[i]);
    					}
    				}
    				break;
    				////////////////////////////
    			}
    			if (geld > preis || geld > 20)
    			{
    				printf("Fehler! Der Automat nimmt nur bis zu maximal 20,00 EURO an.\n\n");
    			}
    			if (geld <= 0)
    			{
    				printf("Fehler! Sie muessen Geld einwerfen um ein Ticket zu kaufen.\n\n");
    			}
    			if (geld != preis && geld < 21 && geld > 0)
    			{
    				rest = preis - geld;
    				printf("Das Geld reicht nicht aus. Es fehlen noch: %.2f EURO\n\n", rest);
    				preis = rest;
    			}
    		} while (geld != preis || geld == rest || geld > 20);
    
    		printf("Zum beenden druecken Sie die Taste 'x'.\n");
    		printf("Zum wiederholen druecken Sie eine andere beliebige Taste.\n");
    		scanf_s(" %c", &c);
    		if (c == 'x' || c == 'X')
    		{
    			return 0;
    		}
    	}
    	return 1;
    }
    

    Das was zwischen den Kommentarzeilen steht ist der Code zur Berechnung der Euros. Nun hab ich versucht die selbe for Schleife für die Cents anzuwenden.
    Also das gleiche nochmal nur mit den Variablen:
    j,anzahlCent, munzenCent[] = {0.5, 0.2, 0.1}
    Wenn ich die zweite Schleife unter die erste schreibe, gibt das Programm trotzdem nur die Euros aus. Wieso ist das so? Und wie kann ich das Lösen?
    Bin dankbar für jeden Tipp und jede Erklärung.



  • Rechne ganzzahlig in Cent.
    Das ist bei Geldbeträgen immer besser.

    Bei Fleiußkommazahlen kommt es zu Ungenauigkeiten, weil manche Zahlen nicht exakt darstellbar sind.
    So wie 1/3 im Dezimalsytem unedlich Stellen hat, so ist es z.B die 0.110 im Binärsystem nicht exakt darstellbar.

    Zur Eingabe kannst du float/double benutzen. Danach aber gleich umrechnen.

    Bei preis = 3.50 * (float)4; ist der cast nach float überflüssig. Da 3.50 schon ein double ist und 4 automatisch nach double gecastet wird.
    So würde die float 4.0 nochmal nach double gecastet.

    Behandle die Preis- und Ticketberechnung getrennt (Fahrtpreis, Anzahl_Tickets) und berechne am Ende den Preis.

    "\n" hat bei deinem Formatstring für scanf keine Auswirkung, da %d automatisch Whitespace (dazu gehört \n) überliest.
    Bei %c ist das anders. Da ist das Leerzeichen (hat dieselbe Wirkung wie \n) davor wichtig.



  • Vielen Dank erstmal für deine Antwort. Einige Dinge wie die floats vor der 4 und das \n bei scanf hab ich korrigiert und auch verstanden warum.

    Was du mit Ticket und Preis getrennt berechnen meinst versteh ich gerade nicht wirklich. Wäre nett wenn du mir das mal konkret an einem Beispiel erläuterst, da das Programm ja so wie ich es jetzt hab gut funktioniert.

    Aber die Rückgabe des Wechselgeldes funktioniert nun super nachdem ich ich das erstmal in Cent umgerechnet hab. Doch ich hab folgendes festgestellt:

    - wenn das Array so da steht = {200, 100, 50, 20, 10, 5, 2, 1};
    und ich das rueckgeld * 100 nehme berechnet er mir die Münzen nur bis 20 Cent,
    also gibt aus : 1 x 0.20 EURO z.b obwohl noch 10 Cent fehlen.

    - dann hab ich einfach mal ausprobiert mit 1000 zu multiplizieren, also:
    Array = {2000, 1000, 500, 200, 100, 50, 20, 10} und rueckgeld * 1000
    und dann erst gibt er mir auch die 10 Cent aus, aber warum ?

    Muss ich außerdem bei den Arrays am Ende immer eine 0 hinzufügen? Habe das mal gelesen aber es funktioniert auch ohne.



  • Hier nochmal der momentane Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <Windows.h>
    #include <string.h>
    
    int main()
    {
    	unsigned int auswahlPreisstufe, auswahlTicket;
    	float preis, geld, rest, rueckgeld;
    	int muenzen[] = { 2000, 1000, 500, 200, 100, 50, 20, 10 };
    	int anzahl;
    	char c;
    
    	while (1)
    	{
    		SetConsoleTitle("Wechselgeldautomat");
    		do
    		{
    			printf("Waehlen Sie eine der folgenden Preisstufen aus:\n");
    			printf("(1) Kurzstrecke: 1,20 EURO\n");
    			printf("(2) Preisstufe A: 2,30 EURO\n");
    			printf("(3) Preisstufe B: 3,50 EURO\n\n");
    			printf("Ihre Auswahl: ");
    			scanf_s("%d", &auswahlPreisstufe);
    
    			switch (auswahlPreisstufe)
    			{
    			case 1: printf("Sie haben sich fuer: '(1) Kurzstrecke: 1,20 EURO' entschieden.\n\n"); break;
    			case 2: printf("Sie haben sich fuer: '(2) Preisstufe A: 2,30 EURO' entschieden.\n\n"); break;
    			case 3: printf("Sie haben sich fuer: '(3) Preisstufe B: 3,50 EURO' entschieden.\n\n"); break;
    			default: printf("Eingabe ungueltig! Bitte wiederholen\n\n"); break;
    			}
    		} while (auswahlPreisstufe < 1 || auswahlPreisstufe > 3);
    
    		do
    		{
    			printf("Waehlen Sie nun zwischen den beiden Tickets:\n");
    			printf("(1) EinzelTicket\n");
    			printf("(2) 4erTicket\n\n");
    			printf("Ihre Auswahl: ");
    			scanf_s("%d", &auswahlTicket);
    
    			switch (auswahlTicket)
    			{
    			case 1: printf("Sie haben sich fuer: '(1) EinzelTicket' entschieden.\n\n"); break;
    			case 2: printf("Sie haben sich fuer: '(2) 4erTicket' entschieden.\n\n"); break;
    			default: printf("Eingabe ungueltig! Bitte wiederholen\n\n"); break;
    			}
    		} while (auswahlTicket < 1 || auswahlTicket > 2);
    
    		do
    		{
    			if (auswahlPreisstufe == 1 && auswahlTicket == 1)
    			{
    				preis = 1.20;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 2 && auswahlTicket == 1)
    			{
    				preis = 2.30;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 3 && auswahlTicket == 1)
    			{
    				preis = 3.50;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 1 && auswahlTicket == 2)
    			{
    				preis = 1.20 * 4;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 2 && auswahlTicket == 2)
    			{
    				preis = 2.30 * 4;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			if (auswahlPreisstufe == 3 && auswahlTicket == 2)
    			{
    				preis = 3.50 * 4;
    				printf("Der Preis betraegt: %.2f EURO\n\n", preis);
    			}
    			break;
    		} while (preis);
    
    		do
    		{
    			printf("Werfen Sie bitte das Geld ein: ");
    			scanf_s("%f", &geld);
    
    			if (geld == preis)
    			{
    				printf("Vielen Dank! Entnehmen Sie bitte Ihr Ticket.\n\n");
    				break;
    			}
    			if (geld > preis && geld < 21)
    			{
    				printf("Vielen Dank! Entnehmen Sie bitte Ihr Ticket und Ihr Rueckgeld.\n\n");
    				rueckgeld = geld * 1000 - preis * 1000;
    				printf("Rueckgeld: %.2f EURO\n\n", rueckgeld / 1000);
    
    				for (int i = 0; i <= (sizeof(muenzen) / sizeof(muenzen[i])); i++)
    				{
    					anzahl = rueckgeld / muenzen[i];
    					if (anzahl > 0)
    					{
    						rueckgeld = rueckgeld - anzahl * muenzen[i];
    						printf("%d x %.2f EURO Muenze(n)\n", anzahl, (float)muenzen[i] / 1000);
    					}
    				}
    				break;
    			}
    			if (geld > preis || geld > 20)
    			{
    				printf("Fehler! Der Automat nimmt nur bis zu maximal 20,00 EURO an.\n\n");
    			}
    			if (geld <= 0)
    			{
    				printf("Fehler! Sie muessen Geld einwerfen um ein Ticket zu kaufen.\n\n");
    			}
    			if (geld != preis && geld < 21 && geld > 0)
    			{
    				rest = preis - geld;
    				printf("Das Geld reicht nicht aus. Es fehlen noch: %.2f EURO\n\n", rest);
    				preis = rest;
    			}
    		} while (geld != preis || geld == rest || geld > 20);
    
    		printf("\nZum beenden druecken Sie die Taste 'x'.\n");
    		printf("Zum wiederholen druecken Sie eine andere beliebige Taste.\n");
    		scanf_s(" %c", &c);
    		if (c == 'x' || c == 'X')
    		{
    			return 0;
    		}
    	}
    	return 1;
    }
    

    So bin ich von der Funktion her sehr zufrieden aber das mit * 1000 kapier ich nicht, warum es mit * 100 nicht ging zumindest die 10 Cent Muenzen.

    Außerdem hab ich noch 5, 2, und 1 Cent hinzugefügt, damit das Programm dann wenigstens das Wechselgeld auf den Cent genau ausgibt, weil ich noch nicht weiß wie ich die Eingabe von z.B 3.88 € verbiete. Ein Tipp dazu wäre auch gut.
    Vielen Dank!



  • wilkaro205 schrieb:

    So bin ich von der Funktion her sehr zufrieden aber das mit * 1000 kapier ich nicht, warum es mit * 100 nicht ging zumindest die 10 Cent Muenzen.

    Die komplette Berechnung muss ganzzahlig ablaufen.
    preis, geld, rest, rueckgeld; sollten auch int sein. Für die Eingabe (nur dafür) brauchst du noch ein float

    DirkB schrieb:

    so ist es z.B die 0.1 im Binärsystem nicht exakt darstellbar.

    10 Cent sind 0.1€

    wilkaro205 schrieb:

    Was du mit Ticket und Preis getrennt berechnen meinst versteh ich gerade nicht wirklich.

    switch (auswahlPreisstufe)
                {
                case 1: Ticketpreis = 120; printf("Sie haben sich fuer: '(1) Kurzstrecke: 1,20 EURO' entschieden.\n\n"); break;
                case 2: Ticketpreis = 230; printf("Sie haben sich fuer: '(2) Preisstufe A: 2,30 EURO' entschieden.\n\n"); break;
                case 3: Ticketpreis = 350; printf("Sie haben sich fuer: '(3) Preisstufe B: 3,50 EURO' entschieden.\n\n"); break;
                default: printf("Eingabe ungueltig! Bitte wiederholen\n\n"); break;
                }
    ......
                switch (auswahlTicket)
                {
                case 1: Anzahltickets = 1; printf("Sie haben sich fuer: '(1) EinzelTicket' entschieden.\n\n"); break;
                case 2: Anzahltickets = 4; printf("Sie haben sich fuer: '(2) 4erTicket' entschieden.\n\n"); break;
                default: printf("Eingabe ungueltig! Bitte wiederholen\n\n"); break;
                }
    

    Dann bleibt für die komische (warum überhaupt die Schleife*) do - while (preis);*Schleife

    preis = Ticketpreis *Anzahltickets ;
    

    Bei Cent musst du statt geld < 21 dann geld <= 2000 nehmen.
    (denn jetzt kannst du noch 20.99 eingeben)

    wilkaro205 schrieb:

    Muss ich außerdem bei den Arrays am Ende immer eine 0 hinzufügen? Habe das mal gelesen aber es funktioniert auch ohne.

    Nein, muss nicht.
    Die wird manchmal als Endekennung benutzt.

    Dabei sehe ich gerade, das du zu weit durch das Array gehst.
    Bei for (int i = 0; i <= (sizeof(muenzen) / sizeof(muenzen[0])); i++) muss es nur < heißen.

    Mit der 0 am Ende vom Array wäre das so:

    for (int i = 0; muenzen[i] > 0; i++)
    


  • Ja genau.. das mit mit 0.1€ hattest du ja vorhin erwähnt, wie blöd von mir. Jetzt wird mir alles klar.
    Ich werde dennoch zur meiner nächsten Aufgabe gehen, da hauptsächlich nur die Funktionalität bewertet wird und das Programm zwar nicht schön geschrieben ist aber dafür gut funktioniert.
    Ich versuche demnächst als Übung das Programm so umzuschreiben wie du es vorgeschlagen hast.
    Vielen Dank!



  • wilkaro205 schrieb:

    ... und das Programm zwar nicht schön geschrieben ist aber dafür gut funktioniert.

    Wenn ich bei Kurzstrecke und Einzelticket 1 Euro und zweimal 10 Cent eingebe, ist das Programm noch nicht zufrieden..
    Wenn ich dann noch 1 Euro nachwerfe, gibt es nur 0.99 wieder raus.



  • Ja genau.. das habe ich später dann auch festgestellt.
    Dann schreibe ich es halt einmal um und beginne sofort mit Cent zu rechnen und am ende bei der Ausgabe dann umrechnen. Damit sollte das ja gelöst sein, wenn ich alles richtig mache stimmts?



  • So, ich habs jetzt so gemacht wie du es gesagt hast. Ich denke das wars dann, oder siehst du noch etwas, dass Probleme machen könnte.

    #include <stdlib.h>
    #include <stdio.h>
    #include <Windows.h>
    
    int main()
    {
    	int auswahlPreisstufe, auswahlTicket, preisTicket, anzahlTicket;
    	int preis, rest, wechselgeld;
    	float geld;
    	int muenzen[] = { 200, 100, 50, 20, 10, 5, 2, 1 };
    	int anzahl;
    	char c;
    
    	while (1)
    	{
    		SetConsoleTitle("Wechselgeldautomat");
    		do
    		{
    			printf("Waehlen Sie eine der folgenden Preisstufen aus:\n");
    			printf("(1) Kurzstrecke: 1,20 EUR\n");
    			printf("(2) Preisstufe A: 2,30 EUR\n");
    			printf("(3) Preisstufe B: 3,50 EUR\n");
    			printf("Ihre Auswahl: ");
    			scanf_s("%d", &auswahlPreisstufe);
    
    			switch (auswahlPreisstufe)
    			{
    			case 1: preisTicket = 120; printf("Sie haben sich fuer: '(1) Kurzstrecke: 1,20 EUR' entschieden.\n\n"); break;
    			case 2: preisTicket = 230; printf("Sie haben sich fuer: '(2) Preisstufe A: 2,30 EUR' entschieden.\n\n"); break;
    			case 3: preisTicket = 350; printf("Sie haben sich fuer: '(1) Preisstufe B: 3,50 EUR' entschieden.\n\n"); break;
    			default: printf("Eingabe ungueltig. Bitte wiederholen.\n\n"); break;
    			}
    		} while (auswahlPreisstufe < 1 || auswahlPreisstufe > 3);
    
    		do
    		{
    			printf("Waehlen Sie nun zwischen den beiden Tickets:\n");
    			printf("(1) EinzelTicket\n");
    			printf("(2) 4erTicket\n");
    			printf("Ihre Auswahl: ");
    			scanf_s("%d", &auswahlTicket);
    
    			switch (auswahlTicket)
    			{
    			case 1: anzahlTicket = 1; printf("Sie haben sich fuer: '(1) EinzelTicket' entschieden.\n\n"); break;
    			case 2: anzahlTicket = 4; printf("Sie haben sich fuer: '(2) 4erTicket' entschieden.\n\n"); break;
    			default: printf("Eingabe ungueltig! Bitte wiederholen.\n\n"); break;
    			}
    		} while (auswahlTicket < 1 || auswahlTicket > 2);
    
    		preis = preisTicket * anzahlTicket;
    		printf("Der Preis betraegt: %.2f EUR\n\n", (float)preis / 100);
    
    		do
    		{
    			printf("Werfen Sie bitte das Geld ein: ");
    			scanf_s("%f", &geld);
    			geld = geld * 100;
    
    			if (geld == preis)
    			{
    				printf("Vielen Dank! Entnehmen Sie bitte Ihr Ticket.\n\n"); 
    				break;
    			}
    			if (geld > preis && geld <= 2000)
    			{
    				printf("Vielen Dank! Entnehmen Sie bitte Ihre Ticket und Ihr Wechselgeld.\n\n");
    				wechselgeld = geld - preis;
    				printf("Wechselgeld: %.2f EUR\n", (float)wechselgeld / 100);
    
    				for (int i = 0; i < sizeof(muenzen) / sizeof(muenzen[i]); i++)
    				{
    					anzahl = wechselgeld / muenzen[i];
    					if (anzahl > 0)
    					{
    						wechselgeld = wechselgeld - anzahl * muenzen[i];
    						printf("%d x %.2f EUR Muenze(n)\n", anzahl, (float)muenzen[i] / 100);
    					}
    				}
    				break;
    			}
    
    			if (geld <= 0)
    			{
    				printf("Fehler! Sie muessen Geld einwerfen um ein Ticket zu erhalten.\n\n");
    			}
    
    			if (geld > preis || geld > 2000)
    			{
    				printf("Fehler! Der Automat nimmt nur bis zu maximal 20,00 EUR an.\n\n");
    			}
    			if (geld != preis && geld <= 2000 && geld > 0)
    			{
    				rest = preis - geld;
    				printf("Das Geld reicht nicht aus! Es fehlen noch %.2f EUR\n\n", (float)rest / 100);
    				preis = rest;
    			}
    		} while (geld != preis || geld == rest || geld > 2000);
    
    		printf("\nZum beenden druecken Sie die Taste 'x'.\n");
    		printf("Zum wiederholen druecken Sie eine andere beliebige Taste.\n");
    		scanf_s(" %c", &c);
    
    		if (c == 'x' || c == 'X')
    		{
    			return 0;
    		}
    	}
    	return 1;
    }
    


  • wilkaro205 schrieb:

    S..., oder siehst du noch etwas, dass Probleme machen könnte.

    scanf_s ist kein 1:1 Ersatz für scanf
    Es verhält sich bei einigen Formatspecifieren anders, bzw. braucht es noch zusätzliche Parameter.

    (Du kannst diese spezielle Warnung von VS auch deaktivieren)

    Achte aber sonst auf die Compilerwarnungen (stelle den Warnlevel auf Maximum)



  • Alles klar. Danke für deine Hilfe.
    VG


Log in to reply