Probleme avec plusieur while.

Fermé
yacinebosss Messages postés 157 Date d'inscription jeudi 27 décembre 2012 Statut Membre Dernière intervention 18 décembre 2021 - 19 juin 2014 à 23:40
yacinebosss Messages postés 157 Date d'inscription jeudi 27 décembre 2012 Statut Membre Dernière intervention 18 décembre 2021 - 28 juin 2014 à 19:26
bon j'ai un petit jeux qui s'appelle le plus ou moins mais quand je répond a la question pour recommencer le jeux il ne le répété pas depuis le DO du WHILE . mais depuis un WHILE qui se trouve dans le premier WHILE. voici mon programme:

int main(int argc, char *argv[])
{
int NombreMystere;
int LeNombreProposer;
int NombreDeTours=1;
int ContinuerLaPartie=1;
int NiveauDeDifficulte;
int ModeDeJeux;//LES VARIABLE.
int NombreMinimal,NombreMaximal;
do//execute le programme en moins une fois.
{

printf("\n");
printf(" ************LE PLUS OU MOIN************\n\n\n\n");//TITRE DU JEU.

printf("CHOISIR LE MODE DE JEU:\n\n");

printf(" 1JOUEUR.\n\n");

printf(" 2JOUEUR.");

printf("\n\n");

while (ModeDeJeux>2||ModeDeJeux==0)
{
printf("\n");
printf(" _QUEL EST VOTRE CHOIX DE MODE:");
scanf("%d",&ModeDeJeux);
printf("\n");
if (ModeDeJeux>2||ModeDeJeux==0)
{
printf(" VEYEZ CHOISIR ENTRE 1 ET 2 ,S.V.P.MERCI!!!");
}
printf("\n");
}
switch (ModeDeJeux)
{
case 1:
printf("\n\n\n");
printf(" Niveau0: ENTRE 0 ET 10 (TRES FACILE)\n\n");
printf(" Niveau1: ENTRE 1 ET 100 (FACILE)\n\n");
printf(" Niveau2: ENTRE 10 ET 1000 (DIFFICILE)\n\n");
printf(" Niveau3: ENTRE100 ET 10000 (MISSION IMPOSSIBLE)\n\n\n");

while (NiveauDeDifficulte>3)//REPETE LA QUESTION DU CHOIX SI LE JOUEUR NOTRE PAS LE BON NOMBRE.
{
printf("\n\n");
printf(" _QUEL EST VOTE CHOIX DE NIVEAU:");

scanf("%d",&NiveauDeDifficulte);

printf("\n");

if (NiveauDeDifficulte>3)
{
printf(" _VEYEZ CHOISIR UN CHIFFRE ENTRE 0 ET 3 S'IL VOUS PLAIT.MERCI!!");
}//EN CAS DE MAUVAIS CHOIXDU JOUEUR.

}
printf("\n\n");
switch (NiveauDeDifficulte)
{
case 0:NombreMinimal =0,NombreMaximal =10,printf("\n\n"),printf("///// ENTRE 0 ET 10 \\\\\\\\\\ \n\n\n");
break;

case 1:NombreMinimal =1,NombreMaximal =100,printf("\n\n"),printf("///// ENTRE 1 ET 100 \\\\\\\\\\ \n\n\n");
break;

case 2:NombreMinimal =10,NombreMaximal =1000,printf("\n\n"),printf("///// ENTRE 10 ET 1000 \\\\\\\\\\ \n\n\n");
break;

case 3:NombreMinimal =100,NombreMaximal =10000,printf("\n\n"),printf("///// ENTRE 100 ET 10000 \\\\\\\\\\ \n\n\n"); //C POUR POUVOIR CHOISIR LE NIVEAU (C'EST PAS ENCORE FINI).
break;

} //CHAQUE CASE CORESPOND A UN NIVEAU.
srand(time(NULL));
NombreMystere = (rand() % (NombreMaximal - NombreMinimal + 1)) + NombreMinimal;
break;

case 2:
printf("\n\n\n");
printf("CHOISIR LE NOMBRE MYSTERE:");
scanf("%d",&NombreMystere);

printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
break;
}

while (LeNombreProposer !=NombreMystere)//CONDITION DE LA BOUCLE.
{
printf("_PROPOSER Un Nombre:");

scanf("%d",&LeNombreProposer);
printf("\n\n"); /*EN POSE UNE QUESTION QUI PEUT ETRE REPOSER
SI LE JOUEUR NE DONNE PAS LA BONNE REPONSE*/
if (NombreMystere>LeNombreProposer)
{
printf("Plus!!!\n\n");
}
else if (NombreMystere==LeNombreProposer&&NombreDeTours==1)
{
printf("===BRAVO===.VOUS AVEZ GAGNER En %d Coups,PAPAPAPAPA VOUS ETE UN GENIE.\n\n\n\n\n\n",NombreDeTours);
}

else if (NombreMystere==LeNombreProposer&&NombreDeTours<=10)
{
printf("===BRAVO===.VOUS AVEZ GAGNER En %d Coups.\n\n\n\n\n\n.",NombreDeTours);
}

else if (NombreMystere==LeNombreProposer&&NombreDeTours>10)
{
printf("===BRAVO===.VOUS AVEZ GAGNER En %d Coups,DESOLE MAIS VOUS ETE NUL.\n\n\n\n\n\n.",NombreDeTours);
}
else if (NombreMystere==LeNombreProposer&&NombreDeTours>30)
{
printf("===BRAVO===.VOUS AVEZ GAGNER En %d Coups,OHHH LALAAA!!!MAIS COMME VOUS ETE NULLL.\n\n\n\n\n\n.",NombreDeTours);
}

else
{
printf("Moins!!!\n\n"); /*LES INDICATIVE QUI SONT DONNER POUR AIDEZ
LE JOUEUR A TROUVER LA REPONSE*/
}
NombreDeTours++;//INCREMONTATION DE LA VARIBLE.

}
printf("Vous Les Vous Rejouer?(taper 1 pour rejouer et 0 pour non):");


scanf("%d",&ContinuerLaPartie); //QUESTION POUR SAVOIR SI LE JOUEUR VEUX RECOMMENCER LA PARTIE OU NON
}


while (ContinuerLaPartie); //CONDITION POUR FERMER LA BOUCLE.



return 0;

}

J'ESPÈRE QUE VOUS ÉTÉ DES PRO ET QUE VOUS COMPRENEZ MON PROGRAMME ET TESTEZ LE DANS VOTRE IDE . PLZ HELP MEEEEE. MERCI.

5 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 20/06/2014 à 15:12
Salut yacinebosss,

Pour poster ton code, fais le en le mettant entre balises code, sinon c'est illisible, comme dit par Twinuts.

Tu fais comme cela :

<code>
printf("Hello world!\n);
</code>

Cela rajoute des couleurs et préserve l'indentation de ton code, qui devient lisible sur le forum.

Par ailleurs, il y a pas mal de problèmes dans ton code.

Tes boucles
while
ne sont jamais exécutées si les valeurs des variables que tu contrôles ne sont pas initialisées à une valeur permettant à la boucle while de s'exécuter au moins une fois. Ou alors, fait des boucles
do while
.

Donc, pour les boucles while, il faudrait initialiser, par exemple, comme cela :

int LeNombreProposer = -1;
int NiveauDeDifficulte = -1;
int ModeDeJeux = -1;


par ailleurs, la variable NombreDeTours est initialisée au début du main à 1. Comme cela te sert à compter le nombre de fois que la personne essaye, il faut la remettre à 1 lorsque la personne choisit de rejouer. Donc
NombreDeTours=1;
devrait figurer dans la première boucle do while.

Ensuite, je crois que tes tests dans les boucles while devraient être corrigés pour couvrir d'autres types d'erreurs.

par exemple :

while ((ModeDeJeux != 1) && (ModeDeJeux != 2))

et
while ((NiveauDeDifficulte < 0) || (NiveauDeDifficulte>3))//REPETE LA QUESTION DU CHOIX SI LE JOUEUR NOTRE PAS LE BON NOMBRE.


me paraissent mieux

Enfin, tu ne vides pas le flux stdin après chaque
scanf
. Pour retirer le
'\n'
et tout ce qui pourrait se trouver à la suite de ce qui est capturé par scanf de façon générale, fais :
while ((c = getchar()) != '\n' && c != EOF)
        /* vidage de stdin */ ;


juste après chaque scanf.

Il te faudra donc un
char c;
dans tes variables.


Dal
2
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
Modifié par sambia39 le 20/06/2014 à 18:39
Bonjour comme je n'arrête pas de voir pas mal d'exercice de plus ou moins sur ce forum, alors je me suis dit que je vais faire pareil du cou, je poste moi aussi un plus ou moins de mon époque avec des erreurs je suis pose à vous d'en jugé à bientôt.

/**
* @Author : Sambia39
* @Licence: GPL v3
* @Mail : admin@xjagercodes.com
* @Web : www.xjagercodes.com
**/

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

/**
* Définition du clear 
* selon le système
**/

#if defined(WIN32) && !defined(UNIX)
 #define clear system("cls")
#elif defined(UNIX) && !defined(WIN32)
 #define clear printf("\033[2J")
#else
 #define clear printf("\033[2J")
#endif


/**
* Fonction de générateur 
* de nombre speudo aléatoire
**/
int f_Rand(const int arg){
 
 static int _seed = 0;
 if(!_seed){
  _seed = 1;
  srand(time(NULL));
 }
 return ( rand() % arg);
}


/**
* Fonction Saisie de nombre 
* et gestion automatique du buffer
**/
int f_GetSaisie(void){
 
 int _ret = 0;
 int _saisie = 0;
 int _nombre = 0;
 
 while(!_saisie){
  
  _ret = scanf("%d%*[^\n]",&_nombre);
  if(!_ret){
   
   int _tmp = 0;
   while( ((_tmp = getchar())!='\n') && (_tmp != EOF) );
   printf("\n[Recommencez] Veuillez Entrer que des nombres\n");
  }
  _saisie = 1;
 }
 return (_nombre);
}

/**
* Teste de nombre
* mistère trouver
***/
int f_GetWin(int iArg, int const iWin){
 
 clear;
 if(iArg < iWin){
  printf(" C'est plus !\n");
  return (0);
 }
 else if( iArg > iWin){
  printf(" C'est Mouins !\n");
  return (0);
 }
 else
  return (1);
}

/**
* Fonction & menu du jeux
**/
int f_Menu(void){
 
 int ret = 0;
 int nombre = 0;
 
 do{
  clear;
  printf( "\t===\tPlus Ou Moins\t===\t\n\n");
  printf("\t\t 1 -> Jouer\n");
  printf("\t\t 2 -> Infos\n\n");
  printf("\t\t 3 -> Quitter\n");
  
  while(!nombre)
   nombre = f_GetSaisie();
  ret = 1;
   
 }while(!ret);
 
 return (nombre);
}

void f_StartGame(void){
 
 clear;
 int Win = 0;
 int loop = 0;
 int ret = f_Menu();
 if( !(ret = f_Config(ret)) )
  ret = 0;
  
 else{
  while(!Win){
   loop = 0;
   while(!loop){
    loop = f_Saisie_Joueur();
   }
   
   Win = f_GetWin(loop,ret);
  }
  
  clear;
  getchar();
  printf("Barvo ! vous avez trouvez le nombre mystere\t %d\a\n",ret);
  printf("Appuyer sur une touche pour revenir au menu ...\n");
  if( getchar() )
   f_StartGame();
 }
}

/**
* Fonction infos
*/
void f_Info(void){
 
 clear;
 printf("Author\t: Sambia39\n");
 printf("Mail\t: admin@xjagercodes.com\n");
 printf("Web\t: www.xjagercodes.com\n");
 
 getchar();
 getchar();
 
 f_StartGame();
}

/**
* Configuration des bornes
*/ 
int f_Config(int const in){
 
 int ret = 0;
 int borne = 0;
  
 switch(in){
  case 1:
   clear;
   printf("Entrer les bornes du nombre mystere\n");
   printf("Exemple\t: 100 donc (0-99)\n");
   while(!borne){
    
    if( (borne = f_GetSaisie()) && (borne <= 5) ){
     printf("la borne doit etre superieur a (5)\n");
     borne = 0;
    }
   }
   
   ret = f_Rand(borne);
   clear;
   break;
  
  case 2:
   f_Info();
   break;
   
  case 3:
   clear;
   printf("Aurevoir\n");
   ret = 0;
   break;
      
  default: break;
 }
 
 return (ret);
}


/**
* Boucle saisie joeur 
**/
int f_Saisie_Joueur(void){
 
 int ret = 0;
 
 while (!ret){
  printf("Quel est le nombre mystère ? \n");
  ret = f_GetSaisie();
 }
 return (ret);
}


/**
* Fonction principale
**/
int main(void){
 
 f_StartGame();
 return (0);
}


Toute connaissance est une réponse à une question.
1
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 2
20 juin 2014 à 10:21
Salut,

Merci de bien vouloir modifier ta question en utilisant les balises "code" et en indentant ce dernier.
0
yacinebosss Messages postés 157 Date d'inscription jeudi 27 décembre 2012 Statut Membre Dernière intervention 18 décembre 2021 3
23 juin 2014 à 21:09
merci a vous deux .mais moi je suit le cour( un livre pour les nuls c son nom) et je ne connais pas encore de char et aussi pour [Dal]:

J'AI PAS BIEN COMPRIS CA :
Enfin, tu ne vides pas le flux stdin après chaque

scanf

. Pour retirer le

'\n'

et tout ce qui pourrait se trouver à la suite de ce qui est capturé par scanf de façon générale, fais :

while ((c = getchar()) != '\n' && c != EOF)
/* vidage de stdin */ ;



juste après chaque scanf.

Il te faudra donc un

char c;

dans tes variables.


MAIS BON JE SUIS QUE AU CHAPITRE 8 ALORS C POUR JE PENSE.
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
24 juin 2014 à 09:16
Bonjour
Personnellement je n'ai rien compris, mais bon étant au chapitre VIII tu as dû forcément voir les chars car le premier chapitre en C du moins le deuxième chapitre en C sont généralement les types, bref peux-tu être claire sur ce que tu avances ?
à bientôt
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 24/06/2014 à 10:40
Salut yacinebosss,

Tu m'interroges sur le sens de ces remarques.

Enfin, tu ne vides pas le flux stdin après chaque scanf.

Pour retirer le '\n'

et tout ce qui pourrait se trouver à la suite de ce qui est capturé par scanf de façon générale, fais :

while ((c = getchar()) != '\n' && c != EOF)
/* vidage de stdin */ ;

juste après chaque scanf.

Il te faudra donc un char c; dans tes variables.


Les systèmes d'exploitation gèrent habituellement le clavier au terminal avec un tampon mémoire, et mettent à disposition son contenu sous la forme d'un flux, le flux d'entrée standard (stdin).

Pour illustrer le problème, on va faire un test sur ton code, où chronologiquement, tu as 3 scanf qui demandent chacun un entier :

- le 1er demande un entier de 1 à 2 (1 ou 2 joueurs)
- le 2ème demande un entier de 0 à 3 (niveau)
- le 3ème demande un entier (tentative du joueur, avec une boucle sur ce scanf tant que le nombre mystère n'est pas trouvé)

Si à 1ère question je réponds :
1 0 5
et je valide, qu'arrive-t-il si chaque scanf n'est pas suivi de l'instruction proposée de vidage du flux ?

Il arrive ceci :

 ************LE PLUS OU MOIN************



CHOISIR LE MODE DE JEU:

1JOUEUR.

2JOUEUR.


_QUEL EST VOTRE CHOIX DE MODE:1 0 5





Niveau0: ENTRE 0 ET 10 (TRES FACILE)

Niveau1: ENTRE 1 ET 100 (FACILE)

Niveau2: ENTRE 10 ET 1000 (DIFFICILE)

Niveau3: ENTRE100 ET 10000 (MISSION IMPOSSIBLE)




_QUEL EST VOTE CHOIX DE NIVEAU:




///// ENTRE 0 ET 10 \\\\\


_PROPOSER Un Nombre:

Moins!!!

_PROPOSER Un Nombre:

Les questions sur le niveau et sur le nombre à deviner sont passées sans que le terminal ne s'arrête.

Pourquoi ?

parce que :

- le 1er scanf prend 1 dans le flux, ce qui satisfait sa demande... mais, le flux stdin n'est pas vide pour autant, il reste
<espace>0<espace>5<\n>
dedans
- au 2ème scanf, le système fournit à scanf ce que contient le flux, scanf ignore l'espace vide et prend 0 dans le flux, ce qui satisfait sa demande,
- comme le flux n'est toujours pas vide, le 3ème scanf prend ce qui reste, ignore l'espace vide et prend 5 dans le flux, ce qui satisfait sa demande,
- à ce stade on est dans ta boucle où le while demande les propositions de nombre, le flux n'est toujours pas vide, car il reste le retour à la ligne dedans
'\n'
, qui est aussi un caractère vide pour scanf', il est ignoré, mais il n'y a plus rien à la suite, et donc ce scanf déclenche une demande de nouvelle entrée à l'utilisateur.

En vidant le flux stdin après chaque scanf, ce genre de mésaventures n'arrive pas. Le flux est vide pour le prochain scanf, et une nouvelle entrée au clavier est bien systématiquement demandée.

http://www.cplusplus.com/reference/cstdio/scanf/


Dal
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
24 juin 2014 à 11:20
Bonjour @Dal
Très bien expliquer mais vers la fin je pense qu'il va légèrement être paumé
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 24/06/2014 à 12:29
Salut sambia39, merci.

La clef de la compréhension est de réaliser que scanf gère un flux qui est alimenté par tout ce qui est dans le tampon mémoire du clavier et que lorsque l'utilisateur tape entrée, le tampon est remplit de ce que l'utilisateur a tapé y compris le retour à la ligne. Ce flux sera traité par chaque appel à scanf : tant qu'il y a quelque chose à consommer dans le tampon, le flux stdin alimente scanf (et toute autre fonction qui utilise stdin, comme getchar,...).

Mais laissons yacinebosss s'exprimer :-)


Dal
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
24 juin 2014 à 13:20
Oui , c'est vrais à toi de jouer yacineboss ^^
0
yacinebosss Messages postés 157 Date d'inscription jeudi 27 décembre 2012 Statut Membre Dernière intervention 18 décembre 2021 3
Modifié par yacinebosss le 26/06/2014 à 21:59
Merci beaucoup a vous deux . j'ai pas bien compris la fin du premier message, mais grâce au deuxième et après avoir relu la fin du premier 2 ou 3 fois :). j'ai très bien compris. merci beaucoupppppp . et j'ai juste deux autre question:

1_Est ce que je dois mettre toutes les variable (Int je pense que ça s'appelle comme ca ^^) après le DO de WHILE ?

2_je dois juste copier la chose pour vider le flux ou ca a un sens. bon dans le cour que je suit il nous ont donner une chose (je ne sais pas comment ca s'appelle) pour générai un nombre aléatoirement et il fallait juste le copier et le coller dans mon code source et il nous ont dit que l'on va le comprendre plus tard ( dans le cour pas dans notre vie ^^) c'est le cas maintenant ?

_BONUS: pourquoi il faut absolument mettre un char ?( dsl je sais que je trouve toujours des question ou il n'y a pas XD).
merci.
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
27 juin 2014 à 11:49
1_Est ce que je dois mettre toutes les variable (Int je pense que ça s'appelle comme ca ^^) après le DO de WHILE ?

Tu peux laisser tes déclarations et initialisations de variables comme elles sont, avec les modifications proposées :

(...)
int main(int argc, char *argv[])
{
    int NombreMystere;
    int LeNombreProposer = -1;
    int NombreDeTours;
    int ContinuerLaPartie=1;
    int NiveauDeDifficulte = -1;                                                                                                                                                                                   
    int ModeDeJeux = -1;
    int NombreMinimal,NombreMaximal;
    int c;
    do//execute le programme en moins une fois.
    {
        NombreDeTours = 1;

        printf("\n");
        printf(" ************LE PLUS OU MOIN************\n\n\n\n");//TITRE DU JEU.
(...)


Par exemple, devrait aller.


2_je dois juste copier la chose pour vider le flux ou ca a un sens. bon dans le cour que je suit il nous ont donner une chose (je ne sais pas comment ca s'appelle) pour générai un nombre aléatoirement et il fallait juste le copier et le coller dans mon code source et il nous ont dit que l'on va le comprendre plus tard ( dans le cour pas dans notre vie ^^) c'est le cas maintenant ?

Je pense que tu parles de :

while ((c = getchar()) != '\n' && c != EOF)
            /* vidage de stdin */ ;


C'est la façon standard de procéder pour vider le flux stdin. Elle est représentée sous une forme assez compacte que permet le C. Ce qui est à l'intérieur des parenthèses while sera évalué tant que la condition sera vraie (comme dans toute boucle while). Ce qui est à l'intérieur des parenthèses while fait ceci :

- on va chercher un caractère sur stdin avec getchar() et on le met dans c
- et on teste si ce caractère est différent du caractère de fin de ligne ('\n')
- et différent de EOF (EOF signifie End Of File, c'est une macro qui renvoie un nombre entier négatif qui signifie que le flux s'est terminé)
- si la condition est vraie, cela signifie qu'il y a toujours quelque chose dans stdin, et on consomme un nouveau caractère en répétant le test

Comme tu le vois, il n'y a pas d'accolades, juste un ; car ce qui est contenu dans l'évaluation de la condition suffit à notre besoin.


_BONUS: pourquoi il faut absolument mettre un char ?( dsl je sais que je trouve toujours des question ou il n'y a pas XD).

pour
getchar()
, déclarer un
int c;
est plus rigoureux que
char c;
car getchar() renvoie un int.

met cette déclaration avec les autres au début de ton main.


Dal
0