Interdire une division par 0

Interdire une division par 0 - C - Programmation

Marsh Posté le 30-09-2006 à 13:44:20    

Bonjour,
 
j'ai réalisé une calculatrice basique.
 
On entre une valeur A, un opérateur (+, -, /, *) et puis une valeur B. On peut effectuer plusieurs calculs.
 
Je voudrais interdire la division par 0, mais je n'y arrive pas... J'ai bien essayé un simple else if((op == '/')&&(b!=0)), mais ça termine brusquement.
 
Je cherche à avoir une message d'erreur du style "Division par 0 interdite", et pouvoir ensuite rerentrer une valeur B.
 
Merci de votre aide.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. float a, b;
  4. float RESULTAT;
  5. char op;
  6. char rep;
  7.      void main()
  8.      {
  9.          
  10.      rep='o';
  11.          while(rep=='o')
  12.   {
  13.                printf("Entrer le reel A : " );
  14.                scanf("%f",&a);
  15.                printf("Entrer un operateur : " );
  16.                scanf("%s",&op);
  17.                printf("Entrer le reel B : " );
  18.                scanf("%f",&b);
  19.             while((op!='+')&&(op!='-')&&(op!='*')&&(op!='/'))
  20.             {
  21.             printf("Entrez soit +, -, * ou /\n" );
  22.             scanf("%s",&op);
  23.             }
  24.                          if(op == '*')
  25.                {
  26.                          RESULTAT=a*b;
  27.                          printf("Resultat : %f\n", RESULTAT);
  28.                }
  29.                          else if(op == '+')
  30.                {
  31.                          RESULTAT=a+b;
  32.                          printf("Resultat : %f\n", RESULTAT);
  33.                }
  34.                          else if((op == '/')&&(b!=0))
  35.                {
  36.                          RESULTAT=a/b;
  37.                          printf("Resultat : %f\n", RESULTAT);
  38.                }
  39.                          else if(op == '-')
  40.                {
  41.                          RESULTAT=a-b;
  42.                          printf("Resultat : %f\n", RESULTAT);
  43.                }
  44.          printf("Voulez-vous effectuer un autre calcul (o/n) ?\n" );
  45.      scanf("%s", &rep);
  46.   }
  47.     }


 

Reply

Marsh Posté le 30-09-2006 à 13:44:20   

Reply

Marsh Posté le 30-09-2006 à 13:52:53    

ba la solution c'est que dans ton while tu prevois une condition de sortie
 

Code :
  1. #include <stdio.h>
  2.  
  3.       #include <stdlib.h>
  4.  
  5.       float a, b;
  6.  
  7.       float RESULTAT;
  8.  
  9.       char op;
  10.  
  11.       char rep;
  12.  
  13.           void main()
  14.           {
  15.                rep='o';
  16.  
  17.               while(rep=='o')
  18.                {
  19.                     printf("Entrer le reel A : " );
  20.                     scanf("%f",&a);
  21.                     printf("Entrer un operateur : " );
  22.                     scanf("%s",&op);
  23.                     printf("Entrer le reel B : " );
  24.                     scanf("%f",&b);
  25.      
  26.                          while((op!='+')&&(op!='-')&&(op!='*')&&(op!='/'))
  27.                          {
  28.                          printf("Entrez soit +, -, * ou /\n" );
  29.                          scanf("%s",&op);
  30.                          }
  31.                               if(op == '*')
  32.                                {
  33.                               RESULTAT=a*b;
  34.                               printf("Resultat : %f\n", RESULTAT);
  35.                                }
  36.                               else if(op == '+')
  37.                                {
  38.                               RESULTAT=a+b;
  39.                               printf("Resultat : %f\n", RESULTAT);
  40.                                }
  41.                               else if(op == '/')
  42.                                {
  43.                                       if(b==0)
  44.                                       {
  45.                                                  printf("Division par 0" );
  46.                                         }
  47.                                       else
  48.                                        {
  49.                                             RESULTAT=a/b;
  50.                                            printf("Resultat : %f\n", RESULTAT);
  51.                                         }
  52.                                }
  53.                               else if(op == '-')
  54.                                {
  55.                               RESULTAT=a-b;
  56.                               printf("Resultat : %f\n", RESULTAT);
  57.                                }
  58.               printf("Voulez-vous effectuer un autre calcul (o/n) ?\n" );
  59.                scanf("%s", &rep);
  60.      
  61.                }
  62.  
  63.          }


 
Mais le switch existe en pas en C?? (je sais plus )
 
Parceque sa serai largement plus propre

Reply

Marsh Posté le 30-09-2006 à 13:55:46    

Si si, le switch avec case je crois existe bien.
 
Mais on débute et notre professeur a voulu que nous réalisions le programme avec un if, histoire de savoir l'utiliser.
 


Message édité par Nichlas le 30-09-2006 à 13:55:56
Reply

Marsh Posté le 30-09-2006 à 13:56:48    

fait d'abord un test (op == '/') et ensuite à l'interieur tu fait un
if (b==0) { afficher message d'erreur }
else { RESULTAT=a/b; printf(....); }
 
Sinon tu utilise mal scanf et les char, tu écris n'importe-ou en mémoire et ne fais aucune vérification de dépassement, ca va te péter à la gueule rapidement si tu corrige pas ca. (lignes 6/7/20/59)
 
[edit]
vala, des if comme dans le code de dreamkiller...


Message édité par 0x90 le 30-09-2006 à 13:58:06
Reply

Marsh Posté le 30-09-2006 à 14:02:18    

Ah ok, j'étais pas loin en fait.
 
J'avais bien fait un if dans le if, mais j'avais mal écrit :  
 
----------------------
 
else if(op == '/')
{
if(b=='0')


Message édité par Nichlas le 30-09-2006 à 14:03:20
Reply

Marsh Posté le 30-09-2006 à 14:06:05    

Citation :

Sinon tu utilise mal scanf et les char, tu écris n'importe-ou en mémoire et ne fais aucune vérification de dépassement, ca va te péter à la gueule rapidement si tu corrige pas ca. (lignes 6/7/20/59)


C'est à dire ?
 
Ligne 6 et 7 tu aurais écrit quoi par exemple ?
 
Tu parles du "double" ?


Message édité par Nichlas le 30-09-2006 à 14:16:16
Reply

Marsh Posté le 30-09-2006 à 14:18:34    

utilise fgets + sscanf. vérifie le retour de toutes ces fonctions.

Reply

Marsh Posté le 30-09-2006 à 14:19:18    

ligne 6 tu déclare un char, ensuite ligne 20 tu utilise scanf pour récupérer un string. Tu as utilisé un & pour avoir l'adresse du char, le compilateur est content il ferme sa gueule MAIS :
- lorsque le scanf récupère un string de longueur 1 ( par exemple "/" ) il fait 2 char de long, le caractère '/' puis le caractère '\0' de fin de chaine. résultat tu écrit le '/' dans op, et tu écris '\0' dans la case mémoire juste après op.
 
Qui, en l'occurence à de fortes chances d'être la cse mémoire ou se trouve rep, si tu fais ca:
rep = 'a';
scanf("%s", &op); /* la tu tappe un truc d'un seul caractère */
printf("%c\n", rep);
le printf ne va pas t'afficher le 'a', parceque le scanf aura écrasé la valeur de rep sans que tu t'en rendre compte. par chance ton code marche malgrès ca.
 
le problème est exactement le même avec rep, en ligne 59 tu écris "illégalement" dans une zone mémoire juste après rep.
 
Ensuite c'est pire, imagine que quelqu'un lors de ton scanf rentre un string superlong, la c'est pas un dépassement d'une case qu'il fait mais de plusieurs cases, ca écrit n'importe-ou après ton char, et la c'est la fête, bonne chance pour débugger quand des variables sont changées involontairement par d'autres ^^
 
La solution c'est de bien relire la doc de scanf (dans le man, ou la: http://xrenault.developpez.com/tutoriels/c/scanf/), tu devrais rapidement trouver de quoi remplacer tes horribles %s.

Reply

Marsh Posté le 30-09-2006 à 14:20:20    

Taz a écrit :

utilise fgets + sscanf. vérifie le retour de toutes ces fonctions.


 
pour récupérer un seul caractère, c'est ptêtre un poil overkill non ? (sinon ouais, pour récuperer des chaines c'est "plus sur". )

Reply

Marsh Posté le 30-09-2006 à 14:24:49    

Merci des tes précisions.
 


Message édité par Nichlas le 30-09-2006 à 14:24:56
Reply

Marsh Posté le 30-09-2006 à 14:24:49   

Reply

Marsh Posté le 30-09-2006 à 14:38:39    

Nichlas a écrit :


Code :
  1. #include <stdio.h>
  2. float a, b;
  3.                          else if((op == '/')&&(b!=0))



On a pas le droit d'utiliser == ou != avec les flottants. Problème de précision. Il faut faire une différence absolue (fabs()) et la comparer avec FLT_EPSILON ou DBL_EPSILON selon le type (<float.h> )
 
C'est une FAQ, non ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 30-09-2006 à 14:39:47    

0x90 a écrit :

pour récupérer un seul caractère, c'est ptêtre un poil overkill non ? (sinon ouais, pour récuperer des chaines c'est "plus sur". )


c'est ça ou du getchar. mais pas de scanf

Reply

Marsh Posté le 30-09-2006 à 14:41:45    

Emmanuel Delahaye a écrit :

On a pas le droit d'utiliser == ou != avec les flottants. Problème de précision. Il faut faire une différence absolue (fabs()) et la comparer avec FLT_EPSILON ou DBL_EPSILON selon le type (<float.h> )
 
C'est une FAQ, non ?


 
Jme suis posé la question justement, s'il n'y a eu aucun calcul et que c'est directement un test après entrée utilisateur, que craint-on comme imprécison ?
Et d'ailleurs si la valeur n'est pas exactement 0, on ne craint justement pas de division par zéro (juste on se tappe un trèèèèès gros chiffre).

Message cité 1 fois
Message édité par 0x90 le 30-09-2006 à 14:43:22
Reply

Marsh Posté le 30-09-2006 à 14:42:46    

Taz a écrit :

c'est ça ou du getchar. mais pas de scanf


 
ouais y'a getchar certes, mais y'a t'il un danger à utiliser un %c tout seul ?

Reply

Marsh Posté le 30-09-2006 à 14:43:52    

tu vois bien la différence entre getchar et %c

Reply

Marsh Posté le 30-09-2006 à 14:44:36    

0x90 a écrit :

Jme suis posé la question justement, s'il n'y a eu aucun calcul et que c'est directement un test après entrée utilisateur, que craint-on comme imprécison ?
Et d'ailleurs si la valeur n'est pas exactement 0, on ne craint justement pas de division par zéro (juste on se tappe un trèèèèès gros chiffre).


/ 0.0 ça va sortir un inf
/ 0 ça va planter.

Reply

Marsh Posté le 30-09-2006 à 14:47:47    

Taz a écrit :

/ 0.0 ça va sortir un inf
/ 0 ça va planter.


 
'fectivement j'ai dit une connerie, faut que jrévise mes flottants moi un de ces 4 :/ (que j'ai vaguement tendance à fuir étrangement... )

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed