Partage
  • Partager sur Facebook
  • Partager sur Twitter

Pendu : Création d'un menu

Tp de Mathieu Nebra

Sujet résolu
    18 février 2017 à 18:28:41

    Bonjour,

    Je post ce message car je ne trouve pas une solution sur le forum qui colle à mon problème. Je m'explique :

    Avant d'attaquer la partie gestion du dictionnaire du TP, j'ai décidé de créer une sorte de menu permettant  de choisir si l'on souhaite rejouer ou non.

    Problème : Lorsque l'on rejoue, le programme gère de façon anarchique mon motTrouve (correspondant au lettre découverte (ou pas) par l'utilisateur). En gros, pour le mot "MARRON", si en rejouant je rentre une lettre autre que la première, motTrouve va afficher (par exemple) : "**RRON" (pour un "R" saisi par exemple).

    Je pense que le problème doit être lié à ma fonction lectureCaractere et à la gestion du '\n'

    Je suis sur Ubuntu 16.04 LTS avec Codeblocks 16.01

    Mon Main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    #include "Prototypes.h"
    
    
    
    int main(int argc, char *argv[])
    {
        char choix='O';                     // Choix de l'utilisateur : O==> jouer n ==> exit
    do                                      //DO ==> tant que l'utilisateur veut jouer
    {
        //-------------Variables-------------
        char *motSecret="MARRON",*motCrypte=NULL,*motTrouve=NULL;
        char lettreSaisie=0;
        int i=0, nombreCoup=10, trouvee=0, longueur=0,fin=0 ;
        int *lettreTrouvee=NULL;
        longueur=strlen(motSecret);
        motCrypte=malloc(longueur*sizeof(char));
        lettreTrouvee=malloc(longueur*sizeof(int));
        motTrouve=malloc(longueur*sizeof(char));
    
        printf("\nLettre Saisie:%c\n",lettreSaisie);
    
        //-------------Programme-------------
        for(i=0;i<longueur;i++) //On mesure la taille du mot secret et on le crypte par des '*'
        {
            motCrypte[i]='*';
        }
    
        //------------- En-tête-------------
        printf("                 -------------------LE PENDU-------------------\n\n\nBienvenu dans le jeu du pendu !!!\n\n");
        printf("Saurez-vous deviner ce mot dans le nombre de coups imparti ?\n\nCoup restant: %d\n",nombreCoup);
        printf("\nLe mot est: %s\n\n",motCrypte); // On affiche le mot crypte
    
          do
          {
              printf("\nsaisissez une lettre:\n ");
              lettreSaisie=LectureCaractere();                 // saisi de la lettre par l'utilisateur
              trouvee=RechercheLettre(lettreSaisie,motSecret,lettreTrouvee);  // on regarde si la lettre est présente dans le mot Si oui trouvee=1
              printf("\nLettre Saisie:%c\n",lettreSaisie);
    
           if(trouvee==1)
           {
               AfficheMot(lettreTrouvee,longueur,motTrouve,motSecret);  // On affiche le nouveau mot avec les lettres découvertes
               printf("\n");
               for(i=0;i<longueur;i++)
               {
                   printf("%c",motTrouve[i]);
               }
           }
           else
           {
               printf("Perdu!!\n");     // Si la lettre rentrée n'est pas dans le mot, on affiche "Perdu" et on retire un coup
               nombreCoup--;
               printf("Il vous reste %d coups\n",nombreCoup);
           }
    
           fin=strcmp(motSecret,motTrouve);     //fin prend la valeur 0 lorsque le mot toruvé est identique au mot secret
    
    
          }while(nombreCoup>0 && (fin!=0));   //On continu tant que l'utilisateur à des coups et que le mot secret n'est pas découvert en entier
          if(fin==0)
            {
                printf("\nBravo!! Vous avez gagné!!\n");    // si l'utlisateur trouve le mot, on le félicite
            }
          else if(fin!=0)
          {
              printf("\n\n\nDommage... Vous avez perdu!!\n"); // sinon on lui signale qu'il a perdu
          }
    
    //-------------Libération mémoire-------------
        free(lettreTrouvee); // On libère l'espace mémoire alloué
        free(motTrouve);
        free(motCrypte);
    
          do                                                    //Permet de rejouer ou non
          {
          printf("\nvoulez-vous rejouer? O/n :\n");
          choix=LectureCaractere();
          printf("\nChoix : %c\n",choix);
          }while(choix!='O'&&choix!='o'&&choix!='n'&&choix!='N');
    
    
    }while(choix=='O');                                         // tant que l'utilisateur veut jouer...sinon exit et...
    printf("\nDommage!! Au revoir!!\n\n");                          //...affiche un message de départ
        return 0;
    }
    
    

    Mes Fonctions (dans Main.c) :

    //-------------Fonctions-------------
    
    
    char LectureCaractere()
    {
        char maLettre=0;
        maLettre=getchar();                 // l'utilisateur saisi un caractère
        maLettre=toupper(maLettre);         // Ce caractère est mis en majuscule
        while(getchar()!='\n');             //  On boucle en ne faisant rien tant que l'on appuie pas sur entrée
        return maLettre;                    //On renvoie le caractère en majuscule
    }
    
    int RechercheLettre(char lettreSaisie, char *motSecret, int *lettreTrouvee)
    {
        int i=0,trouvee=0;
        for(i=0;motSecret[i]!='\0';i++)     // On parcourt notre mot secret
        {
    
    
            if(lettreSaisie==motSecret[i])      //Si mon caractère est présent dans le mot secret...
            {
                lettreTrouvee[i]=1;             //... alors On place un 1 en position i...
                trouvee=1;                      // ... et le booléen trouvee prend VRAI
            }
    
    
        }
        return trouvee;                         // On renvoie trouvee
    }
    char AfficheMot(int *lettreTrouvee,int longueurMot, char *afficheMot, char *motSecret)
    {
        int i=0;
        for(i=0;i<longueurMot;i++)      // On parcourt notre tableau d'entier lettreTrouvee
        {
            if(lettreTrouvee[i]==1)        // Si on à un 1,
            {
                afficheMot[i]=motSecret[i];     // alors le mot que l'on affiche à l'utilisateur prend la lettre correspondante à notre motSecret, en position i....
            }
            else
            {
                afficheMot[i]='*';              //...Sinon on affiche une '*' en position i
            }
        }
        return afficheMot;                      // On renvoie le mot à l'utilisateur
    }
    

    Mes prototypes (Prototypes.h) :

    #ifndef Prototypes.h
    #define Prototypes.h
    char LectureCaractere();
    int RechercheLettre(char lettreSaisie, char *motSecret, int *lettreTrouvee);
    char AfficheMot(int *lettreTrouvee,int longueurMot, char *afficheMot, char *motSecret);
    #endif // Prototypes
    

    Voilà.

    Dans l'attente de vos réponses ;)

    P.S : hésitez pas à crtiquer le code.



    -
    Edité par Niarkx 18 février 2017 à 18:36:36

    • Partager sur Facebook
    • Partager sur Twitter
      22 février 2017 à 18:49:10

      Je n'ai toujours pas trouvé mon erreur quelqu'un pour m'aider s'il vous plaît ? :)
      • Partager sur Facebook
      • Partager sur Twitter
        22 février 2017 à 19:29:32

        Bonsoir, je ne vois à aucun moment ( sauf erreur de ma part ) la zone mémoire pointée par lettreTrouvee initialisée à 0.

        Elle contient donc des valeurs imprévisibles.

        • Partager sur Facebook
        • Partager sur Twitter
          22 février 2017 à 19:48:40

          Bonsoir, 

          Merci de ta réponse ASW_ ;) 

          int *lettreTrouvee=NULL;

          C'est pas ça ? 

          • Partager sur Facebook
          • Partager sur Twitter
            22 février 2017 à 19:54:51

            Non, je parlais de la zone mémoire fournis par malloc ^^ :

            lettreTrouvee=malloc(longueur*sizeof(int)); // main.c ligne:21

            Pour résoudre ce problème, initialise les valeurs se trouvant de l'adresse (lettreTrouvee) à (lettreTrouver + longueur - 1) à 0.

            -
            Edité par ASW_ 22 février 2017 à 20:00:53

            • Partager sur Facebook
            • Partager sur Twitter
              22 février 2017 à 20:25:46

              D'accord merci j'ai compris pourquoi ! 

              J'ai fait : 

              calloc(longueur, sizeof(int));

              Et le problème est réglé

              Néanmoins je n'ai pas compris ce que tu m'as expliqué avec le malloc. Du moins comment j'aurai du initialiser lettre Trouvee par :

              lettreTrouvee=malloc(longueur*sizeof(int));
              lettreTrouvee=0;
              C'est ça ? 
              • Partager sur Facebook
              • Partager sur Twitter
                22 février 2017 à 20:48:18

                ASW_ a écrit:

                ... la zone mémoire pointée par lettreTrouvee initialisée à 0.

                Je parlais de l'initialisation du contenue de la zone mémoire renvoyée par malloc, et pas de lettreTrouvee si tu relis bien :D

                -
                Edité par ASW_ 22 février 2017 à 20:48:46

                • Partager sur Facebook
                • Partager sur Twitter

                Pendu : Création d'un menu

                × 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