Boucle infinie

allobysalut Messages postés 2 Statut Membre -  
fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour, j'ai un problème avec une boucle infinie... quand j'entre une lettre au lieu d'un nombre, sa donne une boucle infinie... voici mon code::

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
int nombreMystere1 = 0, nombreEntre1 = 0, compteur1 = 0, rejouer1 = 1;
const int MAX=100, MIN=1;

while ( rejouer1)
{
int compteur1=0;
srand(time(NULL));
nombreMystere1 = (rand() % (MAX - MIN + 1)) + MIN;
do
{
printf("essayer un nombre : ");
scanf("%d", &nombreEntre1);
compteur1++;

if ( nombreEntre1 < nombreMystere1 )
printf("plus haut ! \n\n");
else if ( nombreEntre1 > nombreMystere1)
printf("plus bas ! \n\n");
else
printf( "\n \n bravo vous avez reussi ! \n");
}
while ( nombreEntre1 != nombreMystere1);
printf(" sa vous a pris %d coups ! \n\n", compteur1);

printf("\n\n voulez-vous rejouer ? \n");
printf(" 0.non \n");
printf(" 1.oui \n");
scanf("%d", &rejouer1);
}
}

4 réponses

  1. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    il faut lire une chaine de caractère et ensuite la convertir en entier. Comme ça, entre les deux, tu peut vérifier que l'utilisateur a bien entrer un nombre.
    C'est la bonne façon de faire.
    1
  2. dehysqop Messages postés 15 Statut Membre
     
    Tu programme avec quoi premièrement?
    0
  3. allobysalut Messages postés 2 Statut Membre
     
    codde::block, en language c
    0
  4. ElementW Messages postés 5690 Statut Contributeur 1 293
     
    Pour illustrer les propos de Char Snipeur, voici un exemple:
    const int MAX=100, MIN=1; 
    char entree[256]; // De quoi stocker ce qu'on va entrer
    /////// LE RESTE DU CODE ///////
    do 
    {
     scanf("%s", entree); // On stocke ce qu'on a marqué
     nombreEntre1 = atoi(entree); // Et avec une fonction plus sure que scanf, on convertit en nombre
    Bon, les plus expérimentés remarqueront que atoi n'est pas safe/sure non plus (strtol l'est par contre); mais atoi est bien mieux que d'utiliser un scanf.

    A l'avenir, essaye de ne plus jamais utiliser scanf pour interpréter ce que l'utilisateur marque, c-à-d pour convertir ce qui est entré en nombre, etc...; cette fonction est bien pratique mais est loin de fonctionner comme il faut; on retrouve souvent ce genre de problèmes avec.

    scanf c'est bon que pour les char*/strings! (mais getchar() c'est encore mieux!)
    0
    1. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      Bon, les plus expérimentés remarqueront que atoi n'est pas safe/sure non plus (strtol l'est par contre); mais atoi est bien mieux que d'utiliser un scanf.
      atoi() est surtout obsolète. Donc à ne pas utiliser.
      Effectivement, il faut utiliser strtol().

      A l'avenir, essaye de ne plus jamais utiliser scanf pour interpréter ce que
      Tout dépend comment on utilise scanf(). Par exemple : scanf("%255s", entree); est beaucoup plus secure que scanf("%s", entree);

      cette fonction est bien pratique mais est loin de fonctionner comme il faut;
      Elle fonctionne comme elle faut. Il faut juste savoir l'utiliser comme elle fonctionne ;-).

      scanf c'est bon que pour les char*/strings! (mais getchar() c'est encore mieux!)
      Pour une chaîne, on utilise fgets(). getchar() c'est pour un seul caractère.
      0
    2. ElementW Messages postés 5690 Statut Contributeur 1 293
       
      Déjà, j'avais oublié de limiter l'entrée (%255). Mais la règle pour l'interprétation reste juste. (Je perds mes habitudes de C, la faute à std::string et ses copains ça)

      "Elle fonctionne comme elle faut". Oui, c'était surtout pour faire peur. N'empêche que parfois on ce demande ce qu'elle arrive a faire, comme ici une boucle infinie alors que nombreEntre1=0. Après, c'est du implementation defined.

      Je parlais de getchar() dans un while adapté.
      0
    3. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      N'empêche que parfois on ce demande ce qu'elle arrive a faire, comme ici une boucle infinie alors que nombreEntre1=0.
      Certes. Mais un simple fgets() ne suffirait pas. Il faut aussi vider le buffer clavier si la chaîne lue est trop grande.
      La bonne façon de faire est :
      #define MAX 256
      /* dans une fonction*/
      char entree[MAX];
      if (fgets(entree, sizeof entree, stdin) != NULL) {
          char *p = strchr(entree, '\n');
          if (p != NULL) {
                *p = '\0';
          }
          else {
               int c;
               while ( (c=getchar()) != '\n' && c!=EOF);
          }
      }
      

      Le mieux est de se créer sa propre fonction.
      Puis après, on utilise strtol() avec les contrôles qui vont bien :-).

      La version avec scanf() est un peu plus simple (même si je ne l'utilise pas trop) : il suffit de boucler jusqu'à ce que scanf() renvoie 1. Le flush du buffer clavier restera quand même obligatoire.

      Cdlt,
      0