Machine à café qui rend la monnaie [Résolu]

Signaler
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021
-
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
-
Bonjour,

Je suis débutant en programmation C, et j'aurais besoin d'un petit coup de pouce si possible. Je dois faire fonctionner une machine à café, et en fonction du prix de la boisson, rendre la monnaie du client. La machine à café peut prendre jusqu'à maximum 10 euros. Mon problème réside dans le fait qu'ayant des nombres décimaux, il m'est impossible d'utiliser un modulo pour récupérer mon reste... Je ne vois pas d'autres alternative possible, et c'est pour cela que je solicite votre aide.
Mon code à pas mal de défauts (je suis vraiment novice ^^'), donc s'il y a quelque chose qui ne se fait pas, ou qui est simplifiable, je suis preneur !!

Voici mon code :





Merci d'avance !

6 réponses

Messages postés
563
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
10 juin 2021
76
Bonjour,

Pour rendre la monnaie, tu n'as pas besoin de faire un modulo (encore moins d'une racine cubique, c'est ce que tu as fait, relis à quoi correspond la fonction
pow()
!)
L'opérateur "magique" à utiliser s'appelle une soustraction!

Et attention, ta succession de
if
pour trouver chacune des pièces ne fonctionne pas. D'une part tu as mal disposé tes accolades fermantes et tes tests d'inégalités ont des "trous" mais même en corrigeant, pour acheter un café au lait avec 1,00 Euro on devra te rendre 2 pièces de 20 centimes. Et ton code ne peut pas gérer le cas où il y a 2 pièces identiques.

Autre info: pour passer des Euros en centimes, c'est une multiplication par 100 qu'il faut utiliser.

Mais aussi, tu n'utilises pas le fait qu'un tableau peut être parcouru. L'enchainement de
if
peut s'écrire en une boucle de quelques lignes.

Attention, ta fonction
achat_boisson()
appelle à un moment ta fonction
achat_boisson()
, ça s'appelle la récursivité, c'est très particulier et ne doit pas être effectué dans ce cas. Pour recommencer, il faut utiliser la boucle
while()
.

Il doit rester d'autres problèmes.
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866
bonjour,
peux-tu partager du texte, et pas des images? merci d'utiliser les balises de code: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

as-tu envisagé de travailler en centimes?
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

Oui, j'avais envisagé d'utiliser le centime comme unité, mais étant donné que mon exercice me contraint à travailler avec des double et non des int, ça ne compile pas...

Voici mon code :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>

// partie A *******************************************************************************

void affichage_boisson ()
{
 printf("╔════════════════════════╦═══════╦═══════╗\n");
 printf("║        BOISSONS        ║ PRIX  ║ CHOIX ║\n");
 printf("╠════════════════════════╬═══════╬═══════╣\n");
 printf("║ Café court ----------- ║  0.70 ║   0   ║\n");
 printf("║ Café long ------------ ║  0.80 ║   1   ║\n");
 printf("║ Café au lait --------- ║  0.60 ║   2   ║\n");
 printf("║ Chocolat ------------- ║  0.50 ║   3   ║\n");
 printf("║ Lait ----------------- ║  0.50 ║   4   ║\n");
 printf("║ Thé au citron -------- ║  0.60 ║   5   ║\n");
 printf("║ Thé à la menthe ------ ║  0.90 ║   6   ║\n");
 printf("║ Thé au gingembre ----- ║  1.20 ║   7   ║\n");
 printf("║ Thé au miel ---------- ║  1.40 ║   8   ║\n");
 printf("║ Zlatan tea ----------- ║  8.75 ║   9   ║\n");
 printf("╚════════════════════════╩═══════╩═══════╝\n");
}

// on a la division  :    B             Q                 R             A
double calcul_monnaie (double n, double quotient, double reste, double rendu)
{
 quotient = rendu / n;
 reste = rendu % n;
 rendu = reste;
 rendu = pow (rendu/10, -3);
 printf("%.2f x %f\n", quotient, n);

return rendu;
}

void achat_boisson (double monnaie_dispo [], double prix_boisson[], int choix, double somme)
{

 double prix, rendu, quotient, reste, n;
 int i;

// initialisation du tableau des différentes monnaies de la machine
 monnaie_dispo [0] = 0.01;
 monnaie_dispo [1] = 0.02;
 monnaie_dispo [2] = 0.05;
 monnaie_dispo [3] = 0.10;
 monnaie_dispo [4] = 0.20;
 monnaie_dispo [5] = 0.50;
 monnaie_dispo [6] = 1;
 monnaie_dispo [7] = 2;
 monnaie_dispo [8] = 5;
 monnaie_dispo [9] = 10;

// initialisation des prix des différentes boissons
 prix_boisson [0] = 0.70;
 prix_boisson [1] = 0.80;
 prix_boisson [2] = 0.60;
 prix_boisson [3] = 0.50;
 prix_boisson [4] = 0.50;
 prix_boisson [5] = 0.60;
 prix_boisson [6] = 0.90;
 prix_boisson [7] = 1.20;
 prix_boisson [8] = 1.40;
 prix_boisson [9] = 8.75;

printf("Quel est votre choix ? - tapez '10' pour quitter -\n");
scanf ("%d", &choix);

if (choix >= 10)
{
 printf("Veuillez saisir une boisson comprise dans le choix...\n");
 scanf ("%d", &choix);
}


 printf("Donnez votre montant : ");
 scanf("%lf", &somme);

// en fonction du choix de l'utilisateur, donne le prix à payer
switch (choix)
{
 case 0 : 
  prix = prix_boisson [0]; 
  break;

 case 1 : 
  prix = prix_boisson [1];
  break; 

 case 2 : 
  prix = prix_boisson [2]; 
  break; 

 case 3 : 
  prix = prix_boisson [3];
  break;

 case 4 : 
  prix = prix_boisson [4];
  break; 

 case 5 : 
  prix = prix_boisson [5];
  break;

 case 6 :
  prix = prix_boisson [6];
  break;

 case 7 : 
  prix = prix_boisson [7];
  break;

 case 8 :
  prix = prix_boisson [8];
  break; 

 case 9 : 
  prix = prix_boisson [9]; 
  break;

 default : 
  exit(-1);
  break;
}

if (somme < prix)
{
 printf("Vous n'avez pas assez de monnaie...");
 printf("\n");
 sleep (3);
 system ("clear");
 affichage_boisson ();
 achat_boisson (monnaie_dispo, prix_boisson, choix, somme);
}

else 
{
 rendu = somme - prix;
 printf("La monnaie à rendre est : %.2f\n", rendu);

 //pour pouvoir trouver le reste, utilisons 1 centimes comme étant notre unité

 for (i = 0; i <= 9; i++)
 {
  prix_boisson [i] = prix_boisson [i] * 10;
  prix_boisson [i] = pow (prix_boisson [i], 3);
 }

 if (rendu < 10000 && rendu > 500)
 {
  n = 500;
  calcul_monnaie (n, quotient, reste, rendu);

  if (rendu < 500 && rendu > 200)
  {
   n = 200;
   calcul_monnaie (n, quotient, reste, rendu);

   if (rendu < 200 && rendu > 100)
   {
    n = 100;
    calcul_monnaie (n, quotient, reste, rendu);

    if (rendu < 100 && rendu > 50)
    {
     n = 50;
     calcul_monnaie (n, quotient, reste, rendu);

     if (rendu < 50 && rendu > 20)
     {
      n = 20;
      calcul_monnaie (n, quotient, reste, rendu);

      if (rendu < 20 && rendu > 10)
      {
       n = 10;
       calcul_monnaie (n, quotient, reste, rendu);

       if (rendu < 10 && rendu > 5)
       {
        n = 5;
        calcul_monnaie (n, quotient, reste, rendu);

        if (rendu < 5 && rendu > 2)
        {
         n = 2;
         calcul_monnaie (n, quotient, reste, rendu);

         if(rendu < 2 && rendu > 1)
         {
          n = 1;
          calcul_monnaie (n, quotient, reste, rendu);
         }
        }
       }
      }
     }
    }
   }
  }
  

 }


}

}

int main ()
{
 int choix;
 double monnaie_dispo [10], prix_boisson[10], somme;

 affichage_boisson ();
 achat_boisson (monnaie_dispo, prix_boisson, choix, somme);
}S
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021
>
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021

Je n'ai trouvé que le langage C# et C++ quand il fallait y préciser le langage... aucune trace du C.
Voici l'énnoncé de l'exercice :


En réalité je recherche le reste, et j'avais déja essayé la formule a = bq + r <=> r = a - bq mais je trouvais le reste = 0...
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866 >
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

ceci est du C

qu'est-ce qui ne compile pas quand tu utilises des centimes?
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021
>
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021

Ca me marque "error: invalid operands to binary % (have 'double' and 'double'), car si j'ai bien compris l'opérateur modulo ne permet pas de trouver le reste...
Par contre, je vais le changer car beaucoup de choses qui peuvent être simplifié.


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>

// partie A *******************************************************************************

void affichage_boisson ()
{
 printf("╔════════════════════════╦═══════╦═══════╗\n");
 printf("║        BOISSONS        ║ PRIX  ║ CHOIX ║\n");
 printf("╠════════════════════════╬═══════╬═══════╣\n");
 printf("║ Café court ----------- ║  0.70 ║   0   ║\n");
 printf("║ Café long ------------ ║  0.80 ║   1   ║\n");
 printf("║ Café au lait --------- ║  0.60 ║   2   ║\n");
 printf("║ Chocolat ------------- ║  0.50 ║   3   ║\n");
 printf("║ Lait ----------------- ║  0.50 ║   4   ║\n");
 printf("║ Thé au citron -------- ║  0.60 ║   5   ║\n");
 printf("║ Thé à la menthe ------ ║  0.90 ║   6   ║\n");
 printf("║ Thé au gingembre ----- ║  1.20 ║   7   ║\n");
 printf("║ Thé au miel ---------- ║  1.40 ║   8   ║\n");
 printf("║ Zlatan tea ----------- ║  8.75 ║   9   ║\n");
 printf("╚════════════════════════╩═══════╩═══════╝\n");
}

// on a la division  :    B             Q                 R             A
double calcul_monnaie (double n, double quotient, double reste, double rendu)
{
 quotient = rendu / n;
 reste = rendu % n;
 rendu = reste;
 rendu = pow (rendu/10, -3);
 printf("%.2f x %f\n", quotient, n);

return rendu;
}

void achat_boisson (double monnaie_dispo [], double prix_boisson[], int choix, double somme)
{

 double prix, rendu, quotient, reste, n;
 int i;

// initialisation du tableau des différentes monnaies de la machine
 monnaie_dispo [0] = 0.01;
 monnaie_dispo [1] = 0.02;
 monnaie_dispo [2] = 0.05;
 monnaie_dispo [3] = 0.10;
 monnaie_dispo [4] = 0.20;
 monnaie_dispo [5] = 0.50;
 monnaie_dispo [6] = 1;
 monnaie_dispo [7] = 2;
 monnaie_dispo [8] = 5;
 monnaie_dispo [9] = 10;

// initialisation des prix des différentes boissons
 prix_boisson [0] = 0.70;
 prix_boisson [1] = 0.80;
 prix_boisson [2] = 0.60;
 prix_boisson [3] = 0.50;
 prix_boisson [4] = 0.50;
 prix_boisson [5] = 0.60;
 prix_boisson [6] = 0.90;
 prix_boisson [7] = 1.20;
 prix_boisson [8] = 1.40;
 prix_boisson [9] = 8.75;

printf("Quel est votre choix ? - tapez '10' pour quitter -\n");
scanf ("%d", &choix);

if (choix >= 10)
{
 printf("Veuillez saisir une boisson comprise dans le choix...\n");
 scanf ("%d", &choix);
}


 printf("Donnez votre montant : ");
 scanf("%lf", &somme);

// en fonction du choix de l'utilisateur, donne le prix à payer
switch (choix)
{
 case 0 : 
  prix = prix_boisson [0]; 
  break;

 case 1 : 
  prix = prix_boisson [1];
  break; 

 case 2 : 
  prix = prix_boisson [2]; 
  break; 

 case 3 : 
  prix = prix_boisson [3];
  break;

 case 4 : 
  prix = prix_boisson [4];
  break; 

 case 5 : 
  prix = prix_boisson [5];
  break;

 case 6 :
  prix = prix_boisson [6];
  break;

 case 7 : 
  prix = prix_boisson [7];
  break;

 case 8 :
  prix = prix_boisson [8];
  break; 

 case 9 : 
  prix = prix_boisson [9]; 
  break;

 default : 
  exit(-1);
  break;
}

if (somme < prix)
{
 printf("Vous n'avez pas assez de monnaie...");
 printf("\n");
 sleep (3);
 system ("clear");
 affichage_boisson ();
 achat_boisson (monnaie_dispo, prix_boisson, choix, somme);
}

else 
{
 rendu = somme - prix;
 printf("La monnaie à rendre est : %.2f\n", rendu);

 //pour pouvoir trouver le reste, utilisons 1 centimes comme étant notre unité

 for (i = 0; i <= 9; i++)
 {
  prix_boisson [i] = prix_boisson [i] * 10;
  prix_boisson [i] = pow (prix_boisson [i], 3);
 }

 if (rendu < 10000 && rendu > 500)
 {
  n = 500;
  calcul_monnaie (n, quotient, reste, rendu);

  if (rendu < 500 && rendu > 200)
  {
   n = 200;
   calcul_monnaie (n, quotient, reste, rendu);

   if (rendu < 200 && rendu > 100)
   {
    n = 100;
    calcul_monnaie (n, quotient, reste, rendu);

    if (rendu < 100 && rendu > 50)
    {
     n = 50;
     calcul_monnaie (n, quotient, reste, rendu);

     if (rendu < 50 && rendu > 20)
     {
      n = 20;
      calcul_monnaie (n, quotient, reste, rendu);

      if (rendu < 20 && rendu > 10)
      {
       n = 10;
       calcul_monnaie (n, quotient, reste, rendu);

       if (rendu < 10 && rendu > 5)
       {
        n = 5;
        calcul_monnaie (n, quotient, reste, rendu);

        if (rendu < 5 && rendu > 2)
        {
         n = 2;
         calcul_monnaie (n, quotient, reste, rendu);

         if(rendu < 2 && rendu > 1)
         {
          n = 1;
          calcul_monnaie (n, quotient, reste, rendu);
         }
        }
       }
      }
     }
    }
   }
  }
  

 }


}

}

int main ()
{
 int choix;
 double monnaie_dispo [10], prix_boisson[10], somme;

 affichage_boisson ();
 achat_boisson (monnaie_dispo, prix_boisson, choix, somme);
}

Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866 >
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

il faut utiliser modulo avec des entiers.
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021
>
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021

D'accord, je crois que j'ai une petite idée, merci !
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

Bonjour,

Si je ne me trompe pas, la soustraction ne me permettrait pas de savoir quels sont les billets/pièces que je dois rendre et leur nombre? J'aurais juste le total que la machine doit rendre au client, non? Excuse moi si je ne t'ai pas bien compris ^^'.

Merci, je me doutais bien que mes if faisaient un peu brouillon... Donc si j'ai bien compris, il me faudrait des boucles while avec des if?

En effet un compteur serait plus pratique, merci !

Merci beaucoup pour ton aide !!
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

Bonjour,

Donc voilà j'ai appliqué vos conseils, et j'obtiens le code ci-dessous. Seuleument petit problème, je n'arrive pas à afficher le nombre de billets/pièce que la machine doit rendre...
J'aimerais avoir une sortie comme ça par exemple :

La monnaie à rendre est : 6.52 euro
1 x 5 euro
1 x 1 euro
1 x 0.5 euro
2 x 0.01 euro

Merci d'avance !

if (somme < prix)
{
	printf("Vous n'avez pas assez de monnaie...");
	printf("\n");
	sleep (3);
	system ("clear");
	affichage_boisson ();
	achat_boisson (monnaie_dispo, prix_boisson, choix, somme);
}

else 
{
	rendu = somme - prix;
	printf("La monnaie à rendre est : %.2f\n", rendu);

	while (rendu > 0)
	{
		for (i = 0; i <= 9; i++)
		{

			if (rendu >= monnaie_dispo [i])
			{
				rendu = rendu - monnaie_dispo [i];
				tab_monnaie [i] = rendu;
			}
		}
	} 
	
	for (i = 0; i <= 9; i++)
	{
		printf("La monnaie : %.2f", tab_monnaie[i]);
	}
}	
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866
qu'affiche ton programme?
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021
>
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021

Il va m'afficher le tableau, les questions etc mais il s’arrête après "la monnaie à rendre est : ..." et c'est tout, on ne quitte pas le programme...
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866 >
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

dans ce cas-là, tu peux ajouter des printf pour t'aider à comprendre ce que fait ton programme.
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021
>
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021

D'accord je vais faire comme ça, merci
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866
je vois que tu as choisi de ne pas travailler en centimes...
Messages postés
563
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
10 juin 2021
76
Bonjour,

En travaillant avec des nombres flottants, il y a un risque que ta boucle
while (rendu > 0)
ne se termine jamais!
Les flottants sont mémorisés en base 2, ils sont normalement affichés en base 10. Mais un nombre peut tomber juste (sans une infinité de décimales) en base 10 mais pas en base 2. C'est une raison pour laquelle nous t'encouragions à travailler sur des centimes où tu n'aurais que des nombres sans décimales dans tes flottants.
Essaie le code :
double x = 0.10;
printf( "%.55f\n" , x ); // je veux 55 chiffres après la virgule
Ça va t'afficher 0.1000000000000000055511151231257827021181583404541015625 Le système ne peut pas mémoriser 0,10 il en prend une valeur approchée. Comme tu le vois c'est très proche mais ça n'est pas 0,10. Donc si tu fais 1.0 - dix fois 0,1 tu obtiens 0.0000000000000001387778780781445675529539585113525390625. Le résultat est très petit mais ça n'est pas zéro!
En t'obligeant à utiliser des flottants peut être que ton prof voulais que tu découvres cette "curiosité".
Les moyens de contourner cette inexactitude sont:
- travailler en centimes qui donneront des résultats justes.
- la prendre en compte en s'attendant à trouver des nombres approximatifs. Est-ce que 1.00 - 2*0.20 est égal, est inférieur ou est supérieur à 0.60? Je ne le sais pas. Mais il en est très proche. On peut considérer que 0.0001 c'est proche de zéro (pour ton exercice.) Ta boucle peut alors s'écrire:
    while ( rendu > 0.0001 )
 {
  for ( int i = 9 ; i >= 0 ; i-- )
  {
   while ( rendu >= monnaie_dispo[i] - 0.0001 )
   {
    rendu -= monnaie_dispo[i];
    tab_monnaie[i]++; // une pièce de monnaie de plus
   }
  }
 }
    printf("Les pieces rendues sont :" );
    for ( int i = 0; i <= 9; i++)
 {
        if ( tab_monnaie[i] > 0 )
      printf( "%f piece de %.2f, ", tab_monnaie[i], monnaie_dispo[i] );
 }
    printf("\n");
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866
je ne pense pas que le prof l'oblige a utiliser des flottants: les paramètres de la fonction sont flottants, c'est tout.
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

Dalfab, je pense avoir compris ce que tu veux dire, il faut maintenant que j'essaye pour voir ce que ça donne.
Merci pour le temps passé à m'expliquer !

Et yg_be, quelle est la différence entre utiliser des flottants et que les paramètres de la fonction soient des flottants? Vu que mes tableaux et mes variables sont en flottants, tu penses peut être à utiliser d'autres variables
int
en plus ?
Messages postés
15979
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 juin 2021
866 >
Messages postés
10
Date d'inscription
dimanche 11 avril 2021
Statut
Membre
Dernière intervention
14 avril 2021

en effet, le type des paramètres n'a rien à voir avec le type des variables utilisées par la fonction.

l'important, c'est d'utiliser des entiers dans les calculs.