Boucle infinie

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. Contributeur
    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
    1. Tu programme avec quoi premièrement?
      0
      1. codde::block, en language c
        0
        1. Contributeur
          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. Contributeur
            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. Contributeur
            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. Contributeur
            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