Programation d'une machine (C++ et ALGO)

Fermé
AlTi5 Messages postés 5 Date d'inscription samedi 27 octobre 2007 Statut Membre Dernière intervention 29 octobre 2007 - 28 oct. 2007 à 00:02
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 29 oct. 2007 à 21:05
Bonjour,

je début une formation de programateur et mon niveau est encore trés bas...

j'ai tenté de faire le programe suivant :

Une machine à café demande 0.40€ pour servir un café
Il ne sert le café qu’après avoir reçu cette somme
Il ne rend pas la monnaie
Il n’accepte pas les pièces de 0.01 et de 0.02


mais sans succes...


Voila le programme que j’ai écrie en algorithme (française) c'est un début

CONST
Prixcafe 0.40

VAR
Somme, Total, Rest =REEL

DEBUT
AFFICHER (« Bonjour les pièces de 0.01 et 0.02 accepté merci pour votre attention »)
AFFICHER (« veuillez entre une somme supérieur a 0.40 centime d’euros»)
SAISIR (nombre)
Rest=Somme - prixcafe
Total=prixcafe - somme

SI (somme>0.02)
AFFICHER (« pièce non reconnue veuillez éviter d’incéré des pièces de 0.01 et 0.02 svp ») ;
SINON SI (total<0.40)
AFFICHER (« il manque encore », total «euros») ;
SINON SI (somme>0.40)
AFFICHER ("Voila un café tt chaud, vous devez récupéré », rest «euros»);
FSI
FIN

je ne sais pas si ma logique est bonne si vous pouviez m'éguiller !

et pour le programé en c++ voila ce que cela donne soyer indulgent svp

#include <stdio.h>
double somme, total, rest;
int main()
{
printf("Bonjour les pièces de 0.01 et 0.02 accepté merci pour votre attention\n");

printf ("veuillez entrer une somme supérieur a 0.40 centime d'euros");
scanf ("%d",&somme);
rest=somme-0.40;
total=0.40-somme;
if (somme<0.02)
{
printf (" pièce non reconnue veuillez éviter d'incéré des pièces de 0.01 et 0.02 svp ");
}
if (somme<0.40)
{
printf(" il manque encore %d euros\n",total);
}
if (somme>0.40)
{
printf("voila un café tt chaud, vous devez récupéré %d euros\n",rest);
}

}
A voir également:

7 réponses

mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
28 oct. 2007 à 02:10
- Pour commencer, pas de variable globale ! Déclare somme, total, rest directement dans la fonction main.
- Ensuite pas besoin d'utiliser des double pour manipuler des valeurs avec deux chiffres après la virgules, des float suffisent amplement.
- Enfin ton main est sensé retourné un int ("int main(){...}) et 0 si tout va bien. Il devrait donc se finir par l'instruction "return 0;"

Voici ce que tu peux faire :
#include <iostream>

// Retourne vrai si c'est une vraie pièce
bool piece_existante(double valeur){
    return valeur == 0.01 || valeur == 0.02 || valeur == 0.05
        || valeur == 0.1  || valeur == 0.2  || valeur == 0.5
        || valeur == 1    || valeur == 2;
}

// Retourne vrai si l'appareil accepte la pièce
bool piece_autorisee(double valeur){
    return piece_existante(valeur) && valeur != 0.01 && valeur != 0.02;
}


int main(){
    const double prix_cafe = 0.4;
    double somme_inseree = 0;
    while(somme_inseree < prix_cafe){
        double piece_inseree;
        std::cout << "Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)" << std::endl
            << "Somme insérée : " << somme_inseree
            << " / Somme demandée " << prix_cafe << std::endl;
        std::cin >> piece_inseree;
        if(!piece_existante(piece_inseree)){
            std::cerr << "Cette pièce n'existe pas !" << std::endl;
        }
        if(!piece_autorisee(piece_inseree)){
            std::cerr << "Cette pièce n'est pas acceptée !" << std::endl;
        }else{
            somme_inseree += piece_inseree;
        }
    }
    std::cout << "Vous avez inséré " << somme_inseree << " pour un café à "
        << prix_cafe <<", je vous rends " << (somme_inseree - prix_cafe) << std::endl;
    return 0;
}

ce qui donne :
Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)
Somme insérée : 0 / Somme demandée 0.4
0.2
Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)
Somme insérée : 0.2 / Somme demandée 0.4
0.3
Cette pièce n'existe pas !
Cette pièce n'est pas acceptée !
Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)
Somme insérée : 0.2 / Somme demandée 0.4
0.01
Cette pièce n'est pas acceptée !
Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)
Somme insérée : 0.2 / Somme demandée 0.4
0.1
Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)
Somme insérée : 0.3 / Somme demandée 0.4
0.5
Vous avez inséré 0.8 pour un café à 0.4, je vous rends 0.4

Bonne chance
0
AlTi5 Messages postés 5 Date d'inscription samedi 27 octobre 2007 Statut Membre Dernière intervention 29 octobre 2007
28 oct. 2007 à 10:49
Oui merci j'avais pensé insérer une fonction tanque (while) mais je ne savais pas comment mi prendre xD
Je vais continuer a travailler le logiciel car a la fin si la somme inséré est supérieur a 0.40 le programme s’arête sans rendre la monnaie ce que tu a pourtant demandé donc ton logiciel


il y a aussi certaine chose que je ne comprend pas
std::endl ;
=\n

std::cout <<
= printf(«

std::cin >> nb ;
=scanf(« %d » ,&nb) ;

std::cerr << "
= ????


Cette ligne ne s’afffiche pas :

std::cout << "Vous avez inséré " << somme_inseree << " pour un café à "
<< prix_cafe <<", je vous rends " << (somme_inseree - prix_cafe) << std::endl;
return 0;

en C++ ca donne donc :


#include <stdio.h>

// Retourne vrai si c'est une vraie pièce
bool piece_existante(double valeur)
{
return valeur == 0.01 || valeur == 0.02 || valeur == 0.05
|| valeur == 0.1 || valeur == 0.2 || valeur == 0.5
|| valeur == 1 || valeur == 2;
}

// Retourne vrai si l'appareil accepte la pièce
bool piece_autorisee(double valeur)
{
return piece_existante(valeur) && valeur != 0.01 && valeur != 0.02;
}

int main()
{
const double prix_cafe = 0.4;
double somme_inseree, rest = 0;

while(somme_inseree < prix_cafe)
{
double piece_inseree;
printf("Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2) \n Somme insérée : %d \n / Somme demandée %d",somme_inseree,prix_cafe);
scanf("%d",&piece_inseree);
if(!piece_existante(piece_inseree))
{
printf("Cette pièce n'existe pas !");
}
if(!piece_autorisee(piece_inseree))
{
printf("Cette pièce n'est pas acceptée !");
}
else
{
somme_inseree += piece_inseree;
}
}
rest=somme_inseree - prix_cafe;
printf("Vous avez inséré %d pour un café à %d, je vous rends %d ",somme_inseree,prix_cafe,rest);
return 0;
}

Sauf que cela ne fonctionne pas xD

Je pence que c’est due au while qui compile mal X_X enfin je ne sais pas j’y es travailler une bonne partie de la nuit pour finalement pondre un truc qui ne fonctionne pas c’est frustrant
0
SmallFitz Messages postés 351 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 21 juin 2013 185
28 oct. 2007 à 16:40
Salut !
Bon je suis peut être lourd.
Mais moi j'apprend le langage C, et en général quand je vois un code en C++ je n'y comprend pas grand chose ^^.
Or là je comprend tout ton code !
La question que je me pose alors c'est : tu codes en C ou en C++ ?
Si c'est en C voilà les conseils que je te donnerais.

Déjà fais gaffe à l'indentation, parce que c'est vraiment illisible.
Avec une bonne indentation voilà ce que ça donne :
/*
Une machine à café demande 0.40€ pour servir un café
Elle ne sert le café qu’après avoir reçu cette somme
Elle ne rend pas la monnaie
Elle n’accepte pas les pièces de 0.01 et de 0.02
Elle n'accepte donc que les pièces de 0.05, 0.10, 0.20, 0.50, 1, 2.
*/

#include <stdio.h>

// Retourne vrai si c'est une vraie pièce
bool piece_existante(double valeur)
{
    return valeur == 0.01 || valeur == 0.02 || valeur == 0.05
    || valeur == 0.1 || valeur == 0.2 || valeur == 0.5
    || valeur == 1 || valeur == 2;
}

// Retourne vrai si l'appareil accepte la pièce
bool piece_autorisee(double valeur)
{
    return piece_existante(valeur) && valeur != 0.01 && valeur != 0.02;
}

int main()
{
    const double prix_cafe = 0.4;
    double somme_inseree , rest = 0;

    while(somme_inseree < prix_cafe)
    {
        double piece_inseree;
        printf("Insérez une pièce (0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1,2)\n");
        printf("Somme insérée : %d\nSomme demandée %d",somme_inseree,prix_cafe);
        scanf("%d",&piece_inseree);
        if(!piece_existante(piece_inseree))
        {
            printf("Cette pièce n'existe pas !");
        }
        if(!piece_autorisee(piece_inseree))
        {
            printf("Cette pièce n'est pas acceptée !");
        }
        else
        {
            somme_inseree += piece_inseree;
        }
    }
    rest=somme_inseree - prix_cafe;
    printf("Vous avez inséré %d pour un café à %d,", somme_inseree, prix_cafe);
    printf("je vous rends %d ", rest);
    return 0;
}


Voilà ce qu'affiche mon compilo :
C:\Users\main.c:4: error: syntax error before "piece_existante"
C:\Users\main.c:5: warning: return type defaults to `int'
C:\Users\main.c:12: error: syntax error before "piece_autorisee"
C:\Users\main.c:13: warning: return type defaults to `int'
C:\Users\main.c:: In function `main':
C:\Users\main.c:25: warning: int format, double arg (arg 2)
C:\Users\main.c:25: warning: int format, double arg (arg 3)
C:\Users\main.c:26: warning: int format, double arg (arg 2)
C:\Users\main.c:41: warning: int format, double arg (arg 2)
C:\Users\main.c:41: warning: int format, double arg (arg 3)
C:\Users\main.c:41: warning: int format, double arg (arg 4)
:: === Build finished: 2 errors, 8 warnings ===


1) Ta fonction piece_existante() :
Je ne connais pas le type bool, peut être qu'il existe, seulement quand je le remplace par le type int (ce qui revient exactement à la même chose) ça affiche moins d'erreurs.
Je pense donc qu'il faut le remplacer par le type int.

2)Ta fonction piece_autorisee() :
Idem.

Avec ces deux petites modifications ça compile.
Mais il reste quand même quelques "détails" à modifier.

3)J'imagine que ton programme est en console.
Tes accents ne sont pas lus. Il faut les enlever.

Au passage je te conseille de mettre en majuscule tes variables qui restent constantes (de type const).
C'est juste pour une question de lisibilité.

4)Ta fonction main ne prend aucun paramètre en entrée, donc il faut mettre
int main(void)


5)Quand tu fais ça,
double somme_inseree, rest = 0;
tu ne peux connaitre la valeur de ta variable somme_inseree.
Or à la ligne suivante tu fais un test sur cette variable !
while(somme_inseree < prix_cafe)
Il faut donc que tu l'initialise à 0 comme tu l'a fait pour la variable rest :
double somme_inseree = 0, rest = 0;


6)Pourquoi demandes-tu à l'utilisateur de rentrer des pièces de 1 ou de 2 cts alors que la machine ne les acceptes pas ?

Avec ces modifications : voilà ce qui s'affiche à l'écran :
Inserez une piece (0.05, 0.10, 0.20, 0.50, 1, 2)
Somme inseree : 0
Somme demandee : 0

Il y a toujours un soucis, la variable prix_cafe n'apparait pas !?
C'est normal... Car elle est de type double, et toi tu veux l'afficher comme si c'était un int.

7)Il faut donc remplacer dans ton printf ceci :
%d
par cela :
%lf

Il faut que tu modifies ça dans tous tes printf, et c'est aussi valable pour tes scanf.

8)Ensuite c'est pas dit que l'utilisateur comprenne que tu attends qu'il rentre quelque chose (il sont parfois couillons les utilisateurs).
Demande donc lui après d'avoir afficher les sommes "insérées" et "demandées".

Avec ces modifications : voilà ce qui s'affiche à l'écran :
Inserez une piece (0.05, 0.10, 0.20, 0.50, 1, 2)
Somme inseree : 0.000000
Somme demandee : 0.400000


9)Je ne sais pas quel IDE tu utilises, mais s'il ne fait pas de pause tout seul à la fin du programme, il se fermera, et tu ne verras rien du tout ! Utilise donc la fonction getchar(); qui attend l'appui sur la touche "Entrée".

10)Un truc qu'il serait juste de modifier, même si n'a pas de répercussion sur le fonctionnement de CE programme :
C'est de déclarer tes variables toujours au début de ton code, et pas dans une condition, comme tu l'as fait là :
while(somme_inseree < PRIX_CAFE)
    {
        double piece_inseree;

Ici ça fonctionne car on rentre toujours dans ta boucle while (en effet somme_inseree est initialisée à 0) mais ça peut créer des erreurs que tu ne trouves pas. C'est pour cela qu'on déclare les variables tout au début d'une fonction, "traditionnellement" ;D

Donc voilà ton code entièrement corrigé, si ça t'es utile :
/*
Une machine à café demande 0.40€ pour servir un café
Elle ne sert le café qu’après avoir reçu cette somme
Elle ne rend pas la monnaie
Elle n’accepte pas les pièces de 0.01 et de 0.02
Elle n'accepte donc que les pièce de 0.05, 0.10, 0.20, 0.50, 1, 2.
*/

#include <stdio.h>

// Retourne vrai si c'est une vraie pièce
int piece_existante(double valeur)
{
    return valeur == 0.01 || valeur == 0.02 || valeur == 0.05
    || valeur == 0.1 || valeur == 0.2 || valeur == 0.5
    || valeur == 1 || valeur == 2;
}

// Retourne vrai si l'appareil accepte la pièce
int piece_autorisee(double valeur)
{
    return piece_existante(valeur) && valeur != 0.01 && valeur != 0.02;
}

int main(void)
{
    const double PRIX_CAFE = 0.4;
    double somme_inseree = 0, rest = 0;

    while(somme_inseree < PRIX_CAFE)
    {
        double piece_inseree;
        printf("Somme inseree : %lf\nSomme demandee : %lf\n",somme_inseree,PRIX_CAFE);
        printf("Inserez une piece (0.05, 0.10, 0.20, 0.50, 1, 2)\n");
        scanf("%lf",&piece_inseree);
        if(!piece_existante(piece_inseree))
        {
            printf("Cette piece n'existe pas !\n");
        }
        if(!piece_autorisee(piece_inseree))
        {
            printf("Cette piece n'est pas acceptee !\n");
        }
        else
        {
            somme_inseree += piece_inseree;
        }

    }
    rest=somme_inseree - PRIX_CAFE;
    printf("Vous avez insere %lf pour un cafe a %lf,", somme_inseree, PRIX_CAFE);
    printf(" je vous rends %lf ",rest);
    getchar();
    return 0;
}


En espérant t'avoir aidé !!
Bon courage pour la suite.

PS: C'est vrai que parfois c'est frustrant, mais quand on a compris et qu'on sait qu'on ne fera plus ces erreurs ça l'est moins, non ?
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
28 oct. 2007 à 19:24
AlTi5

std::endl = \n

Oui sauf qu'en C++ on a un symbole qui traduit mieux end of line (endl) que \n
Donc on s'en prive pas :p

std::cout << = printf(«

Oui pour être plus précis fprintf(stdout,"....
printf ne fait qu'appeler fprintf avec en fichier paramètre stdout (sortie standard).
Sauf que les flux (stream en anglais) permettent de manipuler beaucoup plus facilement les fichiers (car stdin, stdout, stderr respectivement les entrée standard, sortie standard, sortie d'erreur SONT des fichiers) que fprintf ou fscanf.

std::cin >> nb =scanf(« %d » ,&nb) ;

Oui pour être plus précis fscanf(stdin,"...

std::cerr << " = ????

fprintf(stderr,"...
Tout simplement, ce qui consiste à écrire sur la sortie d'erreur standard. Visuellement tout se passe comme si tu écrivais sur la console mais en fait par la suite tu peux faire des redirections de std::cerr et std::cout au moment de lancer ton programme vers d'autres fichiers. Retiens jsute qu'une erreur s'affiche traditionnellement sur std::cerr, et un résultat sur std::cout.

Cette ligne ne s’afffiche pas :

std::cout << "Vous avez inséré " << somme_inseree << " pour un café à "
<< prix_cafe <<", je vous rends " << (somme_inseree - prix_cafe) << std::endl;
return 0;


Si elle s'affiche mais sous windows dès que le programme est exécuté, le fenêtre ms dos est tuée. Il suffit dans ce cas de rajouter devant le return 0 l'instruction :
getchar();


Il faudra peut être ajouter en début de fichier :
#include <cstdio>


Sauf que cela ne fonctionne pas xD

Je pence que c’est due au while qui compile mal X_X enfin je ne sais pas j’y es travailler une bonne partie de la nuit pour finalement pondre un truc qui ne fonctionne pas c’est frustrant


Un programme ne peut pas "mal compiler". Soit il compile (pas d'erreur de compilation), soit il ne compile pas (au moins une erreur de compilation). Un programme peut mal s'exécuter si le code est ambigu (ce qui génère normalement des warnings). Dans la mesure du possible il faut que le programme compile sans warning et sans error (ce qui est le cas du programme que j'ai donné en <1>)

SmallFitz et AlTi5

Smallfitz attention on parle de C++ pas de C. La plupart de tes remarques n'ont un sens qu'en C. Je reprends ci dessous tes remarques afin que tu vois la différence et afin que AlTi5 ne soit pas perdu.

1) Non le type bool est un type standard du C++. Il vaut true (1) ou false (0) et est codé sur un bit. Aucune raison de le changer.
2) Ca compile directement en C++. Si tu utilises un compilateur C (par exemple gcc au lieu de g++) il faut évidemment convertir les types bool en int puisque le type bool n'existe pas en C.
3) Les accents marchent en console. Tu peux les utiliser dans une chaine de caractère mais pas pour nommer tes variables. Tu peux donc conserver tes accents si tu le souhaites. En C++, la convention consiste à éviter les majuscules. On en met juste pour les variables des #define, les paramètres template, et la rigueur on commence les noms de classe par une majuscule. Mais c'est tout.
4) Non le mot clé void ne sert à rien dans ce cas. Il sert juste quand une fonction ne retourne rien.
5) Oui c'est d'ailleurs comme ça que c'était écrit dans le post<1>
6) Oui
7) En fait en C++ les opérateurs << et >> permettent de s'affranchir de ce genre de considération
8) Ce n'est pas très sympa pour l'utilisateur ce que tu dis :) surtout qu'à ce stade c'est encore affiché à l'écran :p
9) Oui mais cette remarque est spécifique à windows.
10) En C oui mais pas en C++. C'est l'un des gros avantages du C++, car chaque variable à une portée limitée à son horizon (la paire d'accolade qui l'englobe) ce qui permet d'écrire ton code beaucoup plus proprement et de désallouer les variables locales à la fonction dès que l'horizon de la variable prend fin. Bref cf <1>

Ici ça fonctionne car on rentre toujours dans ta boucle while (en effet somme_inseree est initialisée à 0) mais ça peut créer des erreurs que tu ne trouves pas. C'est pour cela qu'on déclare les variables tout au début d'une fonction, "traditionnellement" ;D

Ce que tu dis n'a pas de sens la variable a été initialisée à 0 pour cette raison :)

Bonne chance
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
SmallFitz Messages postés 351 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 21 juin 2013 185
29 oct. 2007 à 15:56
Salut !

A AlTi5
Désolé pour la confusion que j'ai pu te causer, c'était vraiment dans le but de t'aider !
;D

A mamiemando
Oups pour ne pas avoir fait la distinction entre C et C++ !
Je ferais gaffe la prochaine fois.

Merci pour tes précisions !
Sauf que pour certaines je ne te suis pas trop...

-J'ai toujours fait des programmes en console et les accents ne sont jamais apparus !
Ils sont remplacés automatiquement par des symboles indésirables.
Chez moi si je veux afficher éèçà dans un printf ça affiche n'importe quoi ^^
C'est pour ça que je ne met jamais d'accents. Tu as une technique pour éviter ça ou alors c'est tout simplement parce que tu codes en C++ ?

-"Non le mot clé void ne sert à rien dans ce cas. Il sert juste quand une fonction ne retourne rien."
Tu parles pour le C++ alors ?
0
AlTi5 Messages postés 5 Date d'inscription samedi 27 octobre 2007 Statut Membre Dernière intervention 29 octobre 2007
29 oct. 2007 à 19:16
Merci a tous pour votre aide le seul problème qui persiste est que je n'est toujours pas a réglé le problème de la fenêtre qui ce ferme a la fin de l’exécution

Et pour la programmation en algo je ne sais pas ce cela est correct


en tout cas merci a toi mamiemando :) pour m'avoir refait la formule et SmallFitz c'est pas grave ca nous permet de progréssé les éreures :)
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
29 oct. 2007 à 21:05
Smallfitz

Ca dépend de ton terminal et de l'encodage utilisé. Sous windows ça se passe peut être mal, mais sous linux par exemple ça marche très bien (aussi bien en C qu'en C++). Il faut dire que le terminal windows est un peu... hum :-)

Pour le mot clé void non ce que j'ai dit vaut aussi bien pour le C que le C++
int f(void){  // void facultatif
 return 0;
}

void f(int x){  // void indispensable
 return x;
}

AlTi5

Tu as ajouté le getchar en fin de programme ?
Si tu reprends ce que j'ai mis dans le post <1> :
#include <cstdio>
#include <iostream>
...
int main(){
...
    std::cout << "Vous avez inséré " << somme_inseree << " pour un café à "
        << prix_cafe <<", je vous rends " << (somme_inseree - prix_cafe) << std::endl;
    getchar();
    return 0;
}

Bonne chance
0