Partage
  • Partager sur Facebook
  • Partager sur Twitter

QU'est ce qui va pas

    22 janvier 2023 à 9:03:30

    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;
    }
    • Partager sur Facebook
    • Partager sur Twitter
      22 janvier 2023 à 11:21:33

      Bonjour,

      while (choix != 'o');

      Là, tu boucles sans fin: le ; est une fin d'instruction, donc ici c'est une instruction vide

      Normalement un while s'écrit comme ceci:

      while(choix != 'o') {
          // on fait des trucs tant que choix est différent de 0
      }




      -
      Edité par Phil_1857 22 janvier 2023 à 11:24:00

      • Partager sur Facebook
      • Partager sur Twitter
        22 janvier 2023 à 11:36:48

        @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.

        • Partager sur Facebook
        • Partager sur Twitter
        ...
          22 janvier 2023 à 12:37:45

          (TLDR; variable choix redéfinie dans la boucle)

          ---

          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 :

          int main()
          {
              char choix = 'a';                   // 1
              srand((unsigned)time(NULL));
              saluer_utilisateur();
          
              do {
                  char choix = 'a';               // 2
                  faire_une_partie();
                  printf("On recommence ? [O] OUI [N] NON\n");
                  scanf_s("%c", &choix);
              } while (choix != 'o');
              return 0;
          }

          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

          • Partager sur Facebook
          • Partager sur Twitter
            22 janvier 2023 à 13:34:36

            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");
            
            }
            Merci encore de votre aide !
            • Partager sur Facebook
            • Partager sur Twitter
              22 janvier 2023 à 14:36:19

              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

              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                23 janvier 2023 à 10:27:19

                Bonjour Rouloude,

                Effectivement, j'avais lu le code un peu "en diagonale"   :-)

                • Partager sur Facebook
                • Partager sur Twitter
                  23 janvier 2023 à 18:27:04

                  Bon, ce genre de code me pose un petit souci

                      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

                  • Partager sur Facebook
                  • Partager sur Twitter
                    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.
                    • Editeur
                    • Markdown