Boucle infinie

allobysalut Messages postés 2 Date d'inscription   Statut Membre Dernière intervention   -  
fiddy Messages postés 11069 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

Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
dehysqop Messages postés 13 Date d'inscription   Statut Membre Dernière intervention  
 
Tu programme avec quoi premièrement?
0
allobysalut Messages postés 2 Date d'inscription   Statut Membre Dernière intervention  
 
codde::block, en language c
0
ElementW Messages postés 4814 Date d'inscription   Statut Contributeur Dernière intervention   1 223
 
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
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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
ElementW Messages postés 4814 Date d'inscription   Statut Contributeur Dernière intervention   1 223
 
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
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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