marthymbiz
Messages postés8Date d'inscriptionmercredi 18 février 2009StatutMembreDernière intervention20 mars 2009
-
19 mars 2009 à 14:00
bzrd
Messages postés20Date d'inscriptionvendredi 13 octobre 2006StatutMembreDernière intervention25 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
Pistol_Pete
Messages postés1053Date d'inscriptionsamedi 2 octobre 2004StatutMembreDernière intervention 9 juillet 20137 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
Pistol_Pete
Messages postés1053Date d'inscriptionsamedi 2 octobre 2004StatutMembreDernière intervention 9 juillet 20137 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
marthymbiz
Messages postés8Date d'inscriptionmercredi 18 février 2009StatutMembreDernière intervention20 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".
bzrd
Messages postés20Date d'inscriptionvendredi 13 octobre 2006StatutMembreDernière intervention25 mars 201136 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).
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
marthymbiz
Messages postés8Date d'inscriptionmercredi 18 février 2009StatutMembreDernière intervention20 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).
marthymbiz
Messages postés8Date d'inscriptionmercredi 18 février 2009StatutMembreDernière intervention20 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.
bzrd
Messages postés20Date d'inscriptionvendredi 13 octobre 2006StatutMembreDernière intervention25 mars 201136 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);
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).