Interdire des valeurs

Interdire des valeurs - C - Programmation

Marsh Posté le 14-10-2006 à 20:34:29    

Bonjour, j'ai un problème...
 
Je souhaite faire un test de valeur en utilisant un "while", interdisant la saisie de chiffres autres que 0 et 1.
 
Ce "while" je pense qu'il faut l'intégrer de suite après le void main(), mais valeur n'est déclaré qu'après...
 
Donc forcement ça plante...

 
--------------
 
Déjà voici le programme, c'est un convertisseur binaire ==> décimal. Le nombre entré par l'utilisateur (ex : 1101) est décomposé en valeur (ex : 1-1-0-1).
 
Chaque valeur est multipliée par une puissance correspondante (ex : 1*2^0 ----- 0*2^1 ----- 1*2^2 ----- 1*2^3)
 
A la fin on fait le total pour avoir le résultat.
 

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<math.h>
  5. char nombre[60];
  6. int indice;
  7. int puissance;
  8. int longueur;
  9. int i; //indice i
  10. int valeur;
  11. double res_final;
  12. void main()
  13. {
  14.     printf("Saisissez un nombre en binaire : " );
  15.     scanf("%s",&nombre);
  16.     longueur = strlen(nombre);
  17.     i=0;
  18.     while (i < longueur)
  19.     {
  20.  printf("%c \n",nombre[i]); // position 2
  21.  valeur = char(nombre[i]) - char('0');
  22.  printf("Valeur numerique de chaque element : %d \n",valeur); 
  23.      
  24.     double y = 2.0, z = i, puiss, res;
  25.       puiss = pow (y, z);       // puiss = 2^i
  26.              res = puiss * valeur;     // 2^i * valeur
  27.    printf("%f\n \n", res);
  28.              res_final = res_final + res;
  29.              i=i+1;                    // progression de i à chaque tour de boucle +1
  30.          
  31.     }
  32.     printf("Resultat decimal : %f\n \n", res_final);
  33. }

Message cité 1 fois
Message édité par Nichlas le 14-10-2006 à 20:37:55
Reply

Marsh Posté le 14-10-2006 à 20:34:29   

Reply

Marsh Posté le 14-10-2006 à 21:28:43    

Nichlas a écrit :

Bonjour, j'ai un problème...
 
Je souhaite faire un test de valeur en utilisant un "while", interdisant la saisie de chiffres autres que 0 et 1.
 
Ce "while" je pense qu'il faut l'intégrer de suite après le void main(), mais valeur n'est déclaré qu'après...
 
Donc forcement ça plante...



 
Forcément... :p  
 
Bon, déjà des remarques d'ordre générales:
- la fonction "main" est de type "int" et non "void"
- mettre des variables en globales est une source potentielle de bug. Vaut mieux les mettre en local
 
Ensuite, ton pb n'est qu'un bête problème d'algo qui se résout de cette façon
FAIRE
    Saisir le nombre
TANT QUE nombre incorrect
 
Ca se traduit en remplaçant le while où le test se fait au début par un do...while où le test se fait à la fin. Enfin vaut mieux utiliser "fgets" et convertir la chaîne saisie en nombre plutôt que de faire saisir directement un nombre dans scanf car si l'utilisateur entre autre chose qu'un nombre, avec fgets tu peux récupérer cet "autre chose" et le gérer alors qu'avec scanf ça va pédaler grave...

char saisie[2];
do {
    printf("saisissez un nombre en binaire\n" );
    fgets(saisie, 2, stdin);
    sscanf(chaine, "%d", &nombre);
} while (nombre < 0 || nombre >1);


 
Maintenant, tu peux utiliser l'algo suivant qui te permet d'afficher un message d'erreur si le nombre est pas bon
TANT QUE VRAI
FAIRE
      SAISIR Nombre
      Si Nombre OK sortir de boucle
      Afficher "Nombre incorrect
FIN FAIRE
 
Là, t'auras une boucle while
 

char saisie[2];
while (1)
{
    printf("saisissez un nombre en binaire\n" );
    fgets(saisie, 2, stdin);
    sscanf(chaine, "%d", &nombre);
    if (nombre >= 0 && nombre <= 1)
        break;
    printf("Nombre incorrect - Recommencez\n" );
}

Message cité 1 fois
Message édité par Sve@r le 14-10-2006 à 21:39:03

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 14-10-2006 à 21:37:19    

Sve@r a écrit :

char saisie[2];
do {
    printf("saisissez un nombre en binaire\n" );
    fgets(saisie, 2, stdin);
    sscanf(chaine, "%d", &nombre);
} while (nombre < 0 || nombre >1);



Alors il faut au minimum {'0', '\n', 0}, soit 3 char... D'autre part, il faut purger en cas de 'trop saisi' et tester le retour de sscanf()...

Code :
  1. int nombre;
  2.    char saisie[3];
  3.    int n;
  4.    do
  5.    {
  6.       printf ("saisissez un chiffre (0 ou 1)\n" );
  7.       fgets (saisie, sizeof saisie, stdin);
  8.       clean (saisie, stdin);
  9.       n = sscanf(chaine, "%d", &nombre);
  10.    }
  11.    while (n != 1 && (nombre < 0 || nombre >1));


avec clean() telle que définie ici :
 
http://www.developpez.net/forums/s [...] ostcount=5

Message cité 1 fois
Message édité par Emmanuel Delahaye le 15-10-2006 à 01:08:20

---------------
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 14-10-2006 à 21:39:41    

Emmanuel Delahaye a écrit :

Alors il faut au minimum {'0', '\n', 0}, soit 3 char... D'autre part, il faut purger en cas de 'trop saisi' et tester le retour de sscanf()...

Code :
  1. char saisie[3];
  2.    int n;
  3.    do
  4.    {
  5.       printf ("saisissez un chiffre (0 ou 1)\n" );
  6.       fgets (saisie, sizeof saisie, stdin);
  7.       clean (saisie, stdin);
  8.       n = sscanf(chaine, "%d", &nombre);
  9.    }
  10.    while (n != 1 && (nombre < 0 || nombre >1));


avec clean() telle que définie ici :
 
http://www.developpez.net/forums/s [...] ostcount=5


 
Zut, j'ai pas pensé au '\n'...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 14-10-2006 à 22:03:11    

J'arrive à comprendre mais le fgets j'ai jamais utilisé...  :pt1cable:  
 
Mais bon apparemment, sans c'est pas faisable... Je vais tenter ça, merci  :)

Reply

Marsh Posté le 14-10-2006 à 23:02:38    

Sve@r a écrit :

Zut, j'ai pas pensé au '\n'...

T'as pas été le seul aujourd'hui  ;)  

Reply

Marsh Posté le 16-10-2006 à 04:25:13    

Nichlas a écrit :

Mais bon apparemment, sans c'est pas faisable... Je vais tenter ça, merci  :)


Si, c'est faisable, mais très dangereux. Le problème de <scanf("%d", &nbr)>, c'est que scanf s'arrête dès qu'elle trouve un caractère qui n'est pas un nombre. Or, quand l'utilisateur tape "12<return>", ces 3 caractères sont stockés dans le buffer d'entrée. scanf récupère facilement le "1" et le "2"... mais laisse le "<return>" dans le buffer. Si, plus tard, tu fais un truc comme "saisir un nom", le scanf ayant déjà un caractère dans son buffer l'utilisera et ne s'arrêtera pas pour te laisser taper. Total, tu crois
1) que ton programme est buggé (ce qui est le cas)
2) que le bug se situe au niveau de la saisie du nom
 
Si tu utilises "fgets", l'ensemble des caractères est vidé du buffer pour être recopiés dans la chaine. Il te suffit ensuite d'exploiter les nombres de cette chaîne et laisser tomber le reste. Et ton buffer étant vide, le scanf suivant s'arrêtera gentiment pour te laisser saisir ton nom...
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 16-10-2006 à 11:54:02    

Sve@r a écrit :

Si tu utilises "fgets", l'ensemble des caractères est vidé du buffer pour être recopiés dans la chaine. Il te suffit ensuite d'exploiter les nombres de cette chaîne et laisser tomber le reste. Et ton buffer étant vide, le scanf suivant s'arrêtera gentiment pour te laisser saisir ton nom...


Quel scanf() ? Autant utiliser exclusivement fgets()...


---------------
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 16-10-2006 à 13:47:32    

Emmanuel Delahaye a écrit :

Quel scanf() ? Autant utiliser exclusivement fgets()...


Ben c'était dans l'hypothétique situation du programmeur qui utilise scanf sans connaitre le danger...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

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