Programme permetant de faire un calcul simple.

Résolu
marthymbiz Messages postés 8 Date d'inscription mercredi 18 février 2009 Statut Membre Dernière intervention 20 mars 2009 - 19 mars 2009 à 14:00
bzrd Messages postés 20 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 25 mars 2011 - 20 mars 2009 à 17:41
Salut tout le monde,
J'ai créé un programme en C qui permet de faire un calcul simple.
Pour se faire, l'utilisateur doit saisir une chaine de caractères sous la forme "opérande1 opérateur opérande2",
une fonction suprEspaces supprimera les espaces, une fonction extractop fera l'extraction de l'opérateur, deux fonctions
extractx1 et extractx2 extrairont les deux opérandes enfin la fonction calcul effectuera l'opération :
voici mon code :
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void suprEspace(char *expr);
void extractop(char *expr,int *ind,char *op);
int extractx1(char *expr,int ind);
int extractx2(char *expr,int ind);
int calcul(int x1,int op,int x2);
void main()
{char expr[255];int ind;char op;int x1,x2,ans;
 printf("Donnez l'expression : ");
 gets(expr);
 suprEspace(expr);
 extractop(expr,&ind,&op);
 x1=extractx1(expr,ind);
 x2=extractx2(expr,ind);
 printf("\n%d\n",x1);
 printf("\n%d\n",x2);
 puts(expr);
 ans=calcul(x1,op,x2);
 printf("\n%s=%d",expr,ans);
 getch();
}

void suprEspace(char *expr)
{int i,j,n;
n=strlen(expr);
for (i=0;i<n;i++)
  if (expr[i]==' ')
                   {
                    for(j=i;j<(n);j++)
                     expr[j]=expr[j+1];
                   }
}

void extractop(char *expr,int *ind,char *op)
{int n,i;
n=strlen(expr);
for (i=0;i<n;i++)
  if ((expr[i]=='+')||(expr[i]=='-')||(expr[i]=='*')||(expr[i]=='/'))
  {*ind=i;
  *op=expr[i];}
  }

int extractx1(char *expr,int ind)
{int i,x;char iks[100];
 for (i=0;i<ind;i++)
    iks[i]=expr[i] ;

x=atoi(iks);
return x;
}
int extractx2(char *expr,int ind)
{int i=0,y;char igrg[100];
 while (expr[i]!='\0')
 {
    igrg[i]=expr[ind+i] ;
    i++; }

y=atoi(igrg);

return y;
}
int calcul(int x1,int op,int x2)
{
 switch(op)
 {
  case '+':
       return (x1+x2);
  case '-':
       return (x1-x2);
  case '*':
       return (x1*x2);

}
return(x1%x2);
}

Borland arrive  a compiler le code mais le programme plante lorsque j'essaie d'effectuer une division et je pense que c'est dû au type de retour lors d'une division.
aussi j'aimerais créer une fonction qui permet de vérifier si l'expression saisie est valide ou pas alors svp faites moi part de vos idées.
MERCI d'avance

12 réponses

Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
19 mars 2009 à 15:01
Dans ta fonction int extractx2(char *expr,int ind)
il faut mettre:
igrg[i]=expr[ind+i+1] ;
Si tu ne mets pas le +1, le premier caractère est l'opérateur. Ca ne gène pas pour atoi() pour le  + et le - mais pour le \, ça ne passe pas.
A+
____________________________________________________________________________
Mon site internet :  
http://ImAnalyse.free.fr
3
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
19 mars 2009 à 14:21
Salut
Pourquoi dans ta fonction calcule la division n'a pas le droit à son "case" dans le switch?
et return(x1%x2);  donne le reste de la division euclidienne, et non pas la division. Il faut utiliser /.
Mais il faut toujours avant une division vérifier que l'on ne divise pas par 0...
A+

____________________________________________________________________________
Mon site internet :  
http://ImAnalyse.free.fr
0
marthymbiz Messages postés 8 Date d'inscription mercredi 18 février 2009 Statut Membre Dernière intervention 20 mars 2009
19 mars 2009 à 14:37
Re,
J'ai fait sortir la division de la structure conditionnelle case parce que si je la remet dans le case le compilateur m'affiche un warning qui est "Function should return a value" et puis quand je l'exécute et que j'effectue une division une fenêtre s'affiche m'indiquant "Thread stopped".
0
bzrd Messages postés 20 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 25 mars 2011 36
19 mars 2009 à 15:02
A mon humble avis, le plus simple c'est ce qui suit
Attention : pas de test ou presque donc il faut peut-être vérifier avant la syntaxe de la chaîne passée (interdire qu'il y ait des doubles opérateurs comme dans "1 +* 2", et vérifier qu'on a bien 2 nombres).

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
   char expr[255];
   char   *ptr;
   int op1, op2, res;
   char operation;

   printf("Donnez l'expression : ");
   gets(expr);
   ptr = strtok(expr, "+-/*%");
   if (ptr != NULL)
      operation = *ptr;
   else
   {
      printf("Il faut un opérateur parmi +,-,/,* et %\n");
      return;
   }
   op1 = atoi(expr);    // premier opérateur
   op2 = atoi(ptr+1);   // second opérateur
   switch(operation)
   {
   case '+':
      res = op1 + op2;
      break;
   case '-':
      res = op1 - op2;
      break;
   case '*':
      res = op1 * op2;
      break;
   case '/':
      if (!op2)
      {
         printf("Le diviseur ne doit pas être nul\n");
         return;
      }
      res = op1 / op2;
      break;
   case '%':
      if (!op2)
      {
         printf("Le diviseur ne doit pas être nul\n");
         return;
      }
      res = op1 % op2;
      break;
   }
   printf("%d %c %d = %d", op1, operation, op2, res);
}

Cordialement
0

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

Posez votre question
marthymbiz Messages postés 8 Date d'inscription mercredi 18 février 2009 Statut Membre Dernière intervention 20 mars 2009
19 mars 2009 à 15:42
Merci Pistol_pete, grâce a cette petite modification le programme fonctionne et effectue les opérations correctement.
mais je voudrais aussi pouvoir effectuer les division qui ont un résultat de type réel.
quant a ton code bzrd apres avoir mis un getch() a la fin quand j'entre une opératon ("1+2") ça m'affiche (1 1 0 = 1).
0
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
19 mars 2009 à 15:49
Pour les reels il faut faire un cast;
int x1=5,x2=2;
double Res = x1/(double) x2;
printf("%f,\n",Res);    //Affiche 2.5

A+

____________________________________________________________________________
Mon site internet :  
http://ImAnalyse.free.fr
0
bzrd Messages postés 20 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 25 mars 2011 36
19 mars 2009 à 16:02
Désolé, erreur au début du code :

void

main()

{
   char expr[255];

   char *ptr;

   int op1, op2, res;
   int   len;                              // changer là

   char operation;

   printf("Donnez l'expression : ");

   gets(expr);

   len = strspn(expr, "1234567890 \t");   // changer là

   ptr = expr + len;                      // et là
...
// le reste est identique
0
marthymbiz Messages postés 8 Date d'inscription mercredi 18 février 2009 Statut Membre Dernière intervention 20 mars 2009
19 mars 2009 à 16:11
je n'arrive pas a intégrer le cast dans ma fonction calcul. 
0
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
19 mars 2009 à 16:19
Le plus simple est de faire tous tes calcules avec des double...

____________________________________________________________________________
Mon site internet :  
http://ImAnalyse.free.fr
0
bzrd Messages postés 20 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 25 mars 2011 36
19 mars 2009 à 16:22
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
   char expr[255];
   char   *ptr;
   float   op1, op2, res;      // Modif  <<<<<<
   char operation;

   printf("Donnez l'expression : ");
   gets(expr);
   ptr = strtok(expr, "+-/*%");
   if (ptr != NULL)
      operation = *ptr;
   else
   {
      printf("Il faut un opérateur parmi +,-,/,* et %\n");
      return;
   }
   op1 = atof(expr);    // premier opérateur      <<<<<<
   op2 = atof(ptr+1);   // second opérateur      <<<<<<

...

  printf("%f %c %f = %f", op1, operation, op2, res);
}

Voilà : tout en float, pas besoin de cast !
0
marthymbiz Messages postés 8 Date d'inscription mercredi 18 février 2009 Statut Membre Dernière intervention 20 mars 2009
20 mars 2009 à 17:17
Merci bzrd pour ton code.
j'aimerais introduire une boucle pour toutes les instructions du genre :
do
 {
 printf("Donnez l'expression : ");
 gets(expr);
 suprEspace(expr);
 extractop(expr,&ind,&op);
 x1=extractx1(expr,ind);
 x2=extractx2(expr,ind);
 printf("\n%d\n",x1);
 printf("\n%d\n",x2);
 puts(expr);
 ans=calcul(x1,op,x2);
 printf("\n%s=%d",expr,ans);

 do
 {printf("\nVoulez vous effectuer une autre opération? o=OUI/n=NON\n\nChoix :\t");
 scanf("%c",&rep);
 }
 while ((rep='o')||(rep='O')||(rep='n')||(rep='N'));

le code comporte quelques warnings mais il s'execute le probleme c'est que la boucle ne fonctionne pas comme je le souhaite.
0
bzrd Messages postés 20 Date d'inscription vendredi 13 octobre 2006 Statut Membre Dernière intervention 25 mars 2011 36
20 mars 2009 à 17:41
Salut,

on dirait que ton while n'est pas bon :
 while ((rep='o')||(rep='O')||(rep='n')||(rep='N'));Comme tu as mis des simples et pas des, tu as des affectations (d'où surement les warnings).

En fait l'équivalent de ton while c'est ça en gros :
rep = 'o';
if (rep == 0) rep='O';
if (rep == 0) rep='n';
if (rep == 0) rep='N';
donc tu te retrouves systématiquement avec rep='o'

Il faudrait mettre 
 while ((rep=='o')||(rep=='O')||(rep=='n')||(rep=='N'));

Mais en plus ton test est inversé, puisque ton while doit s'arrêter quand tu as 'o', 'O', 'N' ou 'n', donc il faut
 while ((rep!='o') && (rep!='O') && (rep!='n') && (rep='N'));

Enfin il manque un while dans l'extrait que tu donnes.
Je te conseille ça :

rep = 'o';   // init pour entrer dans la bouclewhile (rep 'O' || rep 'o')
{
   printf("Donnez l'expression : ");
   gets(expr);
   suprEspace(expr);

   extractop(expr, &ind, &op);
   x1 = extractx1(expr, ind);
   x2 = extractx2(expr, ind);
   printf("\n%d\n", x1);
   printf("\n%d\n", x2);
   puts(expr);
   ans = calcul(x1, op, x2);
   printf("\n%s=%d", expr, ans);

  do
  {
     printf("\nVoulez vous effectuer une autre opération? o=OUI, n=NON\n\nChoix :\t");
     scanf("%c", &rep);
  }
  while ((rep!='o') && (rep!='O') && (rep!='n') && (rep='N'));
}

C'est un peu "simpliste", mais ça me semble correct !

Petite remarque personnelle, je te conseille de mettre systématiquement un espace après chaque virgule (comme en français) pour aérer ton code et idem avant/après la plupart des opérateurs :
      ans = calcul(x1, op, x2);
plutôt que
      ans=calcul(x1,op,x2);
Ca ne coûte rien et c'est plus facile à relire.

Dernier point, en ce qui me concerne j'indente en mettant (comme toi) les { sur une ligne séparée. Avant je les mettais en fin de ligne mais j'ai passé trop de temps à chercher des bugs dûs à une mauvaise indentation, et en plus ça aère le code ! (tout à fait personnel et d'autres défendent la position inverse).

Cordialement
0
Rejoignez-nous