bonjour, je debute en C. je veux faire un programme dans lequel la machine choisi un numero au hasard et l'utilisateur doit le deviner et à la fin on a le choix de recommencer ou pas. Pour la partie devinette ca a l'air de fonctionner, en revanche pour la boucle de choix jai un soucis que j'arrive pas a resoudre. qu'est ce qui va pas ?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
char prenom[100];
int nombreRandom;
char choix = 'a';
printf("Bonjour ! :)\n");
printf("Quel est ton prenom ?\n");
scanf_s("%s", prenom, 10);
printf("Ravi de jouer avec toi, %s !.\n", prenom);
printf("Je vais penser a un nombre entre 1 et 100 et tu devra le deviner.\n\
Je te dirai si le nombre que tu as choisis est plus grand ou \nplus petit que le nombre auquel je pense.\n");
printf("\n");
printf("on commence ?\n");
printf("\n");
do
{
int nombreEntre = 0, nombreRandom;
char choix = 'a';
srand((unsigned)time(NULL));
nombreRandom = (rand() % 100) + 1;
printf("%d", nombreRandom);
printf("Choisis un nombre :\n");
scanf_s("%d", &nombreEntre);
while(nombreEntre != nombreRandom)
if (nombreEntre < nombreRandom)
{
printf("C'est plus !\n");
scanf_s("%d", &nombreEntre);
}
else if (nombreEntre > nombreRandom)
{
printf("C'est moins !\n");
scanf_s("%d", &nombreEntre);
}
printf("\t\t\t BRAVO TU AS TROUVE LE NOMBRE AUQUEL JE PENSAIS !! \t\t\t");
printf("\n");
printf("On recommence ? [O] OUI [N] NON\n");
scanf_s("%c", &choix);
}
while (choix != 'o');
return 0;
}
@Phil_1857 Ici on a affaire à un do while et non pas un while, il faut donc bien le point virgule.
ManuelDeVals a écrit:
en revanche pour la boucle de choix jai un soucis que j'arrive pas a resoudre. qu'est ce qui va pas ?
Il faudrait décrire ton problème (ce qui ce passe réellement et ce que tu attend).
Mais je suppose que la saisie ligne 51 est perturbé par un caractère qui reste dans le buffer clavier pour palier à cela tu peux mettre un espace avant le %c.
EDIT : quand tu dis "j'ai un souci", on serait content de savoir lequel. Ca aiderait à chercher la cause.
----
Bon, d'abord un principe : séparer les problèmes. Programmer, c'est ramener un algorithme de traitement de l'information à des instructions de base du langage de programmation. Dès qu'on fait un truc un peu intéressant, il faudra beaucoup d'instructions, et le souci, c'est qu'on va s'y paumer si on s'organise pas.
Donc on décompose. Et pour ça, les fonctions c'est très utile. Ca donne un nom à une suite d'instructions qu'on définit ailleurs, et qu'on utilise ensuite sans rentrer dans les détails, qui n'interfèrent pas avec ce qu'on fait.
Exemple concret : une partie de ton code s'occupe de faire une partie avec l'utilisateur. Donc tu peux en faire une fonction
void faire_une_partie()
{
int nombreEntre = 0;
int nombreRandom = (rand() % 100) + 1;
printf("%d", nombreRandom); // tricheur !
printf("Choisis un nombre :\n");
scanf_s("%d", &nombreEntre);
while(nombreEntre != nombreRandom) {
if (nombreEntre < nombreRandom) {
printf("C'est plus !\n");
scanf_s("%d", &nombreEntre);
}
else if (nombreEntre > nombreRandom) {
printf("C'est moins !\n");
scanf_s("%d", &nombreEntre);
}
}
printf("\t\t\tBRAVO TU AS TROUVE !!\n");
}
qui s'occupe de ça.
Et ton programme va s'occuper de répéter ça, il s'est beaucoup réduit :
et du coup, comme on a aussi envoyé les printf du début dans une fonction saluer_utilisateur(), on y voit beaucoup plus clair.
En particulier, tu vois que tu as défini deux variables "choix". Tu as le droit en C, mais le problème c'est que la condition du while utilise celle qui est définie en 1, alors que le scanf_s agit sur celle qui est en 2.
Solution => supprimer la déclaration 2.
Ici ca se voit parce que les deux définitions sont seulement à 5 lignes d'écart. Contre 16 dans le tien : tu ne pouvais pas voir les deux en même temps. Même problème de double définition pour nombreRandom.
Un autre souci : tu demandes de taper 0 ou N en majuscule, et tu teste la minuscule, ça va pas aider.
Pendant qu'on y est : les chaînes de caractères peuvent être écrites par morceaux, ça évite d'avoir des printf d'un kilomètre de long si on les met sur plusieurs lignes. Ca évite aussi de faire plusieurs printf
void saluer_utilisateur()
{
char prenom[100];
printf("Bonjour ! :)\n");
printf("Quel est ton prenom ?\n");
scanf_s("%s", prenom, 10);
printf("Ravi de jouer avec toi, %s !.\n", prenom);
printf("Je vais penser a un nombre entre 1 et 100 "
"et tu devra le deviner.\n"
"Je te dirai si le nombre que tu as choisis"
"est plus grand ou "
"plus petit etc\n"
}
- Edité par michelbillaud 22 janvier 2023 à 12:58:39
Ca fonctionne !! Merci pour votre aide. J'ai utilisé des fonctions ce qui facilite en effet la lecture ! (Je viens à peine d'entamer le chapitre sur les fonctions ce matin mais ca va, c'est pas bien compliqué!). Voici le résultat final. C'est le 1er "programme" que je fais, j'en suis plutôt fier même si c'est pas grand chose, ca amusera les enfants !.
void joueur();
void partie();
int main()
{
char choix = 'a';
srand((unsigned)time(NULL));
joueur();
do
{
partie();
printf("On recommence ? [O] OUI [N] NON\n");
scanf_s(" %c", &choix, 1u);
}
while (choix = 'o'&&choix!='n');
return 0;
}
void joueur()
{
char prenom[100];
printf("Bonjour ! :)\n");
printf("Quel est ton prenom ?\n");
scanf_s("%s", prenom, 10);
printf("Ravi de jouer avec toi, %s !.\n", prenom);
printf("Je vais penser a un nombre entre 1 et 100 et tu devra le deviner.\n\
Je te dirai si le nombre que tu as choisis est plus grand ou \n\
plus petit que le nombre auquel je pense.\n");
printf("\n");
printf("on commence ?\n");
printf("\n");
}
void partie()
{
int nombreEntre = 0, nombreRandom;
nombreRandom = (rand() % 100) + 1;
printf("%d", nombreRandom);
printf("Choisis un nombre :\n");
scanf_s(" %d", &nombreEntre);
while (nombreEntre != nombreRandom)
if (nombreEntre < nombreRandom)
{
printf("C'est plus !\n");
scanf_s("%d", &nombreEntre);
}
else if (nombreEntre > nombreRandom)
{
printf("C'est moins !\n");
scanf_s("%d", &nombreEntre);
}
printf("\t\t\t BRAVO TU AS TROUVE !! \t\t\t");
printf("\n");
}
Dans ta fonction partie, tu fais 3 scanf, tu pourrais n'en faire qu'un seul si tu remplaçais le while par un do ... while. Tu places le printf et le scanf en début de boucle.
Ça serait plus facile de compter le nombre de coups si tu le souhaitais.
Si tu inversais le test, ça paraitrais plus logique: if (nombreRandom > nombreEntre) // Supérieur (>)c'est plus printf("C'est plus !\n");
- Edité par PierrotLeFou 22 janvier 2023 à 14:54:41
Le Tout est souvent plus grand que la somme de ses parties.
printf("%d", nombreRandom);
printf("Choisis un nombre :\n");
scanf_s(" %d", &nombreEntre);
while (nombreEntre != nombreRandom)
if (nombreEntre < nombreRandom)
{
printf("C'est plus !\n");
scanf_s("%d", &nombreEntre);
}
else if (nombreEntre > nombreRandom)
{
printf("C'est moins !\n");
scanf_s("%d", &nombreEntre);
}
Le souci, c'est qu'on y trouve 3 fois le scanf.
Pourtant si on demande "en français, ça fait quoi ?", la réponse c'est que c'est du code qui
fait une boucle
à chaque étape, demande un nombre
compare avec le nombre mystere
et affiche trop grand ou trop petit ou s'arrête si on a trouvé.
Y a pas 3 fois "on demande un nombre"
Un code plus naturel, ça serait une boucle "répéter jusqu'à ce que ça soit fini"
bool fini = false;
do {
// demander un nombre
// comparer; arrêter ou faire des trucs
} while (! fini);
avec les détails
bool fini = false;
do {
// demander un nombre
int nombre_entre;
printf("Donnez un nombre : ");
scanf("%d", &nombre_entre);
// comparer, arrêter ou faire des trucs
if (nombre_entre > nombre_mystere) {
printf("trop grand\n");
} else if (nombre_entre < nombre_mystere) {
printf("trop petit\n");
} else {
fini = true;
}
} while (! fini);
perso j'aurais plutôt un faible pour une boucle "infinie" avec break (qui débarrasse d'un indicateur booléen qui veut juste dire "break the loop") mais bon
for(;;) {
// demander un nombre
int nombre_entre;
printf("Donnez un nombre : ");
scanf("%d", &nombre_entre);
// comparer, arrêter ou faire des trucs
if (nombre_entre < nombre_mystere) {
printf("trop petit\n");
} else if (nombre_entre > nombre_mystere) {
printf("trop grand\n");
} else {
break;
}
}
EDIT: corrections diverses
Note : for (;;) c'était la tournure idiomatique pour une "boucle infinie" dans les débuts de C (K & R). Se base sur le fait que les trois éléments du for sont facultatifs, et que par défaut, la condition est vraie. Intérêt : immédiatement reconnaissable.
Fréquemment remplacée par while(1) et, plus moderne while(true).
Pour le boucle avec indicateur d'arrêt, on pourrait avantageusement utiliser la forme
for (bool fini = false; ! stop; ) {
...
if (....) fini = true;
...
}
// ou
for (bool continuer = true; continuer; ) {
...
if (....) continuer = false;
}
qui limite la portée de l'indicateur à ce qui est strictement nécessaire.
- Edité par michelbillaud 26 janvier 2023 à 9:39:54
6 février 2023 à 6:20:46
- Message modéré pour le motif suivant : Merci d’utiliser le bouton code pour inséré un code sur le forum
QU'est ce qui va pas
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Merci encore de votre aide !
Le Tout est souvent plus grand que la somme de ses parties.