Probleme avec plusieur while.
Fermé
yacinebosss
Messages postés
156
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 156 Date d'inscription jeudi 27 décembre 2012 Statut Membre Dernière intervention 18 décembre 2021 - 28 juin 2014 à 19:26
yacinebosss Messages postés 156 Date d'inscription jeudi 27 décembre 2012 Statut Membre Dernière intervention 18 décembre 2021 - 28 juin 2014 à 19:26
A voir également:
- Probleme avec plusieur while.
- While fscanf ✓ - Forum C
- While en assembleur ✓ - Forum Programmation
- Boucle while excel sans vba - Forum Excel
- Factorielle python while ✓ - Forum Programmation
- Error code 1309 mac while copying ✓ - Forum MacOS
5 réponses
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié par [Dal] le 20/06/2014 à 15:12
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>
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
Donc, pour les boucles while, il faudrait initialiser, par exemple, comme cela :
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
Ensuite, je crois que tes tests dans les boucles while devraient être corrigés pour couvrir d'autres types d'erreurs.
par exemple :
et
me paraissent mieux
Enfin, tu ne vides pas le flux stdin après chaque
juste après chaque scanf.
Il te faudra donc un
Dal
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
whilene 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
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
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.
Toute connaissance est une réponse à une question.
/** * @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.
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
20 juin 2014 à 10:21
Salut,
Merci de bien vouloir modifier ta question en utilisant les balises "code" et en indentant ce dernier.
Merci de bien vouloir modifier ta question en utilisant les balises "code" et en indentant ce dernier.
yacinebosss
Messages postés
156
Date d'inscription
jeudi 27 décembre 2012
Statut
Membre
Dernière intervention
18 décembre 2021
3
23 juin 2014 à 21:09
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.
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.
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
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
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié par [Dal] le 24/06/2014 à 10:40
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 :
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 :
Il arrive ceci :
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
- 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
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
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 5et 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
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
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é
Très bien expliquer mais vers la fin je pense qu'il va légèrement être paumé
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié par [Dal] le 24/06/2014 à 12:29
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
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
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
24 juin 2014 à 13:20
Oui , c'est vrais à toi de jouer yacineboss ^^
yacinebosss
Messages postés
156
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
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.
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.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
27 juin 2014 à 11:49
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 :
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 :
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
met cette déclaration avec les autres au début de ton main.
Dal
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