Partage
  • Partager sur Facebook
  • Partager sur Twitter

tp jeu pendu (language c partie 2)

    2 septembre 2021 à 18:22:31

    bonjour j ai commence le tp jeu de pendu , j ai essaye d executer un code ms il n a pas fonctionne .veuillez me guider vers l erreur merci d avance et merci d avance.
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    #include "dico.h"
    
    
    int main()
    {
    
        char* motsecret={0};
         int* mot={0};
         int k=0;
         int lettreentree=0;
    
         motsecret=malloc(sizeof(char)*strlen(motsecret));
         motsecret=aleatoire();
    
        mot=malloc(sizeof(int)*strlen(motsecret));
        if(mot==NULL)
            exit(0);
        for(int j=0;j<strlen(motsecret);j++)
        {
            mot[j]=0;
        }
    
    
        printf("taper une lettre\n");
    
            while(k<10&&!(mottrouve(motsecret,mot)))
            {
                lettreentree=lirecaractere();
                for(int i=0;i<strlen(motsecret);i++)
                     {
                       if (lettreentree==motsecret[i])
                       mot[i]=1;
                       printf("%c",motsecret[i]);
                       printf("vs avez trouve la lettre n %d \n",i);
                     }
                if (strchr(motsecret,lettreentree)==NULL)
                    k++;
                free(motsecret);
                free(mot);
            }
    
    
       if (mottrouve(motsecret,mot))
           {
    
            printf("vs avez gagne\n");
            }}
    int mottrouve(char motsecret[],int mot[])
    
        { int compteur=0;
            for (int h=0;h<strlen(motsecret);h++)
               {
                   if (mot[h]==0)
                 {
                   compteur++;
                 }
               }
            if (compteur!=0)
                return 0;
            else
                return 1;
    
    
    
        }
    char lirecaractere()
    {
        char caractere=getchar();
        caractere=toupper(caractere);
        while(caractere!='\n');
        return caractere;
    
    
    }
     char* aleatoire()
    {
        int caractere=0;int nombredemots=0;int numerodeligne=0; char* motpioche={0};
        FILE* fichier=NULL;
        int compteurb=0;
        fichier=fopen("dico.c","r");
        if(fichier==NULL)
           {
            printf("imposible de telecharger le fichier");
        return 0;
        }
        rewind(fichier);
        do {caractere=fgetc(fichier);
    
        if(caractere=='\n')
           {
            nombredemots++;
            }
            }while(caractere!=EOF);
    
    
        numerodeligne=rand()%nombredemots;
    
        while (compteurb<numerodeligne)
        {
            rewind(fichier);
    
            motpioche=fgets(motpioche,100,fichier);
            motpioche[strlen(motpioche)-1]='\0';
            compteurb++;
        }
        fclose(fichier);
        return motpioche;
    
    
    }
    • Partager sur Facebook
    • Partager sur Twitter
      2 septembre 2021 à 18:25:55

      Bonjour,

      je vais en premier lieu te guider vers un lien qui va te permettre de mieux poser ta question : https://www.biostars.org/p/75548/ 

      Ensuite, un second conseil  : lire les messages du compilateurs, au cas où rajouter les options de compilations qui permettent de les avoir (-Wall -Wextra pour gcc et clang).

      • Partager sur Facebook
      • Partager sur Twitter
        2 septembre 2021 à 19:15:12

        Et aussi, va y par étapes, Testes tes fonctions indépendamment les une des autres : Par exemple testes ta fonction lirecaractere :

        #include <stdio.h>
        #include <ctype.h>
        
        char lirecaractere()
        {
            char caractere=getchar();
            caractere=toupper(caractere);
            while(caractere!='\n');
            return caractere;
        }
        
        int main(void)
        {
            char c = lirecaractere();
            putchar(c);
        
            return 0;
        }

        Et fais la fonctionner correctement avant de passer à la suite ! Sinon tu ne vas pas t'en sortir !

        Et indente correctement ton code, il sera plus facile à lire.

        • Partager sur Facebook
        • Partager sur Twitter
          2 septembre 2021 à 19:26:25

          @White Crow: as-tu lu le code?
          Il y a plein d'erreurs fondamentales.
          @NouhaylaZakaria:
          Je te suggère de faire une version plus simple de ton programme dans laquelle tu fournis le mot mystère directement.
          Après seulement, tu pourras t'essayer avec un fichier.
          Comment peux-tu connaître la longueur à réserver par malloc pour le mot mystère si tu ne sais pas lequel tu vas choisir?
          Si tu fais deux appels à malloc, ça vaut peut-être la peine de faire une fonction où tu vérifies si ça marche.
          etc.
          • Partager sur Facebook
          • Partager sur Twitter

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

            2 septembre 2021 à 20:13:44

            merci pierre j ai deja essaye avec la version simple ms elle n a pas marche voici le code
            #include <stdio.h>
            #include <stdlib.h>
            #include <ctype.h>
            #include <string.h>
            
            
             char lireCaractere();
            int main()
            {
                int k=0;
                char mot[7]="******";
                const char motsecret[7]="MARRON";
                while (((strcmp(mot,motsecret)!=0)&&(k<10)))
                {
            
                int maLettre;
            
                maLettre = lireCaractere();
            
                for(int i=0;i<7;i++)
                {
                   if(maLettre==motsecret[i])
                   {
                       mot[i]=maLettre;
                       printf("%s\n",mot);
            
                   }
            
            
                }
            
                if (strchr(motsecret,maLettre)==NULL)
                   {
            
                    k++;}
            }
                    if(strcmp(mot,motsecret)==0)
                    {
            
                     printf("vs avez trouvez le mot");
                     }
                     else
                    {
                        printf("malheureusement vs n avez pas trouve le mot");
                    }
                    printf("%s",mot);
            
                return 0;
            }
              char lireCaractere()
            {
                char caractere = 0;
            
                caractere = getchar(); // On lit le premier caractère
                caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
            
                // On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
                while (getchar() != '\n') ;
            
                return caractere; // On retourne le premier caractère qu'on a lu
            }
            
            et stp tu peux me guider vers ces erreurs fondamentales

            -
            Edité par NouhaylaZakaria 2 septembre 2021 à 22:12:49

            • Partager sur Facebook
            • Partager sur Twitter
              2 septembre 2021 à 20:23:54

              Tu peux commencer par corriger les erreurs signalées par le compilateur :

              truc.c:5:7: error: conflicting types for ‘strchr’
                  5 | char* strchr(const char* ch,const char* caractereachercher);
                    |       ^~~~~~
              In file included from truc.c:4:
              /usr/include/string.h:226:14: note: previous declaration of ‘strchr’ was here
                226 | extern char *strchr (const char *__s, int __c)
                    |              ^~~~~~
              truc.c: In function ‘main’:
              truc.c:14:24: warning: comparison with string literal results in unspecified behavior [-Waddress]
                 14 |     while ((k<10)&&(mot!="MARRON"))
                    |                        ^~
              truc.c:33:26: warning: passing argument 2 of ‘strchr’ makes pointer from integer without a cast [-Wint-conversion]
                 33 |     if (strchr(motsecret,maLettre)==NULL)
                    |                          ^~~~~~~~
                    |                          |
                    |                          int
              truc.c:5:7: note: expected ‘const char *’ but argument is of type ‘int’
                  5 | char* strchr(const char* ch,const char* caractereachercher);
                    |       ^~~~~~
              truc.c:38:15: warning: comparison with string literal results in unspecified behavior [-Waddress]
                 38 |         if(mot=="MARRON")
                    |               ^~
              

              Ligne 5 : tu as déclaré une fonction qui était déjà déclarée.

              Ligne 14 : tu compares deux chaînes avec '!=', c'est une erreur classique (une chaîne de caractères étant un tableau, on ne peut pas utiliser '==' et '!='). Même erreur ligne 38.

              Ligne 33 : tu as passé en paramètre un entier au lieu d'une chaîne de caractères.

              -
              Edité par robun 2 septembre 2021 à 20:27:36

              • Partager sur Facebook
              • Partager sur Twitter
                2 septembre 2021 à 21:31:57

                oui  merci@robin tu as raison ms je ne sais pas comment traduire la condition mot=="marron" en language c



                -
                Edité par NouhaylaZakaria 2 septembre 2021 à 21:33:21

                • Partager sur Facebook
                • Partager sur Twitter
                  2 septembre 2021 à 21:38:07

                  Alors pour comparer deux chaînes de caractère on utilise la fonction strcmp
                  • Partager sur Facebook
                  • Partager sur Twitter
                    2 septembre 2021 à 21:39:44

                    oui le code a fonctionne merci @rouloude

                    -
                    Edité par NouhaylaZakaria 2 septembre 2021 à 22:11:31

                    • Partager sur Facebook
                    • Partager sur Twitter
                      2 septembre 2021 à 21:41:38

                      PierrotLeFou a écrit:

                      @White Crow: as-tu lu le code?
                      Il y a plein d'erreurs fondamentales.

                      Non. Les messages du genre «j'ai une erreur dans mon code dites moi où elle est» sans plus de détails ou d'implication ne me donnent pas envie d'investir du temps.

                      Il n'y a même pas la description du problème ! et ma boule de cristal est cassée …

                      Si le PO ne fait pas un minimum d'efforts c'est pas la peine, enfin àmha.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        3 septembre 2021 à 0:54:14

                        OK donne nous le code qui fonctionne. On pourra voir si on peut améliorer avant de continuer.
                        Tu peux tester en parallèle de lire le fichier dictionnaire et d'essayer d'afficher les 10 premiers mots.
                        Ensuite, génère un nombre aléatoire entre 0 et 10 et affiche seulement ce mot.
                        Après on pourra parler sérieusement. :)
                        • Partager sur Facebook
                        • Partager sur Twitter

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

                          3 septembre 2021 à 14:00:49

                          oui j ai modifie le code sinon voici le nouveau programme et j ai essaye de faire un programme qui lit un mot du fichier mais il ne fonctionne pas
                          #include <stdio.h>
                          #include <stdlib.h>
                          #include <ctype.h>
                          #include <string.h>
                           
                           
                           char lireCaractere();
                          int main()
                          {
                              int k=0;
                              char mot[7]="******";
                              const char motsecret[7]="MARRON";
                              while (((strcmp(mot,motsecret)!=0)&&(k<10)))
                              {
                           
                              int maLettre;
                           
                              maLettre = lireCaractere();
                           
                              for(int i=0;i<7;i++)
                              {
                                 if(maLettre==motsecret[i])
                                 {
                                     mot[i]=maLettre;
                                     printf("%s\n",mot);
                           
                                 }
                           
                           
                              }
                           
                              if (strchr(motsecret,maLettre)==NULL)
                                 {
                           
                                  k++;}
                          }
                                  if(strcmp(mot,motsecret)==0)
                                  {
                           
                                   printf("vs avez trouvez le mot");
                                   }
                                   else
                                  {
                                      printf("malheureusement vs n avez pas trouve le mot");
                                  }
                                  printf("%s",mot);
                           
                              return 0;
                          }
                            char lireCaractere()
                          {
                              char caractere = 0;
                           
                              caractere = getchar(); // On lit le premier caractère
                              caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
                           
                              // On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
                              while (getchar() != '\n') ;
                           
                              return caractere; // On retourne le premier caractère qu'on a lu
                          }

                          -
                          Edité par NouhaylaZakaria 3 septembre 2021 à 18:31:10

                          • Partager sur Facebook
                          • Partager sur Twitter
                            3 septembre 2021 à 16:57:37

                            Tu peux sauver du code en assignant en même temps que tu déclares:
                            int lettreentree = lirecaractere();
                            Il y a des parenthèses inutiles:
                                while (((strcmp(mot,motsecret)!=0)&&(k<10)))
                            Tu n'est pas obligé d'entourer chaque sous-expression.
                            Je pense que ce serait mieux avec un do {...} while plutôt qu'un while {...}. Tu dois passer au moins une fois dans la boucle.
                            Pour éviter l'appel à strchr, je ferais ceci:
                            + juste avant la boucle pour chercher si le caractère est dans le mot mystère, je ferais  n=1;
                            si je trouve une occurence (ou plus) de la lettre, je fais  n=0; dans le if(...)
                            Après la fin de boucle, je fais  k += n;  qui augmentera seulement si on n'a pas trouvé la lettre.
                            À la fin de la boucle do ... while, je pense que ce serait mieux de tester si  k>=10 plutôt que d'appeler strcmp une autre fois.
                            Tu pourrais te préparer pour la suite en testant la longueur du mot mystère au début et réserver avec malloc l'espace pour mot.
                            Ensuite tu mets des '*' dans mot, suivi d'une fin de schaîne ('\0')
                            -
                            Pour la fonction aleatoire():
                            pas besoin de rewind avant le premier passage.
                            tu ne réserves aucun espace pour la variable pioche, tu devras le faire après le premier passage.
                            Pour savoir comment d'espace réserver, tu comptes le nombre de caractères dans chaque mot (incluant le '\n' et tu trouve la longueur maximum.
                            C'est celle là que tu utiliseras pour pioche (ne pas oublier une position pour le '\0')
                            C'est également cette valeur que tu utiliseras dans le fgerts()
                            Il faut appeler srand() avant l'appel à rand(). Ça te prendra #include <time.h>
                            Je ne sais pas la longueur de ton dictionnaire. J'en ai un de 325000 mots et rand() ne va pas plus loin que 32767.
                            Je ferais  (rand() * 32767) % nombredelignes
                            Ou on utilise le symbole RAND_MAX qui vaut justement 32767.
                            Fais le close avant le return.
                            • Partager sur Facebook
                            • Partager sur Twitter

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

                              3 septembre 2021 à 18:26:05

                              merci pour tes conseils pour ameliorer le premier code quant au deuxieme je pense que l erreur provient du fait que je n ai pas fait l allocation dynamique pour la variable mot[] car on ne sait pas a priori la taille du tableau  donc on doit faire une allocation dynamique.N ' est ce pas?
                              • Partager sur Facebook
                              • Partager sur Twitter
                                3 septembre 2021 à 18:53:28

                                NouhaylaZakaria a écrit:

                                donc on doit faire une allocation dynamique.N ' est ce pas?

                                Tu peux, mais ce n'est pas une obligation, tu pourrais utiliser un tableau suffisamment grand pour contenir le plus grand mot existant.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  3 septembre 2021 à 19:01:26

                                  Tu lis ton fichier deux fois, n'est-ce pas?
                                  Lors de la première lecture, tu comptes le nombre de lignes.
                                  Tu pourrais en même temps compter le nombre de caractères sur chaque ligne et tu le compare au maximum (qui sera 0 au départ).
                                  Tu obtiendra donc la longueur du mot le plus long de ton dictionnaire.
                                  Tu es certain que tous les mots lus avec fgets ensuite ne seront pas aussi long.
                                  motchoisi = fgets(motchoisi, maximum+1, file);
                                  Tu dois en effet réserver de l'espace pour le mot que tu cherches. Ce sera égal au maximum trouvé (plus 1 pour le '\0')
                                  char *motchoisi = malloc(maximum+1);
                                  • Partager sur Facebook
                                  • Partager sur Twitter

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

                                    3 septembre 2021 à 19:02:19

                                    j'ai essaye d'utiliser un grand tableau mais le code ne fonctionne pas ,il renvoie(NULL) et dans le compilateur il s'est ecrit que la fonction retourne l'adresse d'une variable locale.est ce que la variable est consideree comme variable locale? est ce que le pb provient du fait qu il est locale dans la fonction lirefichier().

                                    EDIT:est ce que je dois faire l'allocation dans la fonction main ou dans lirefichier()?

                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    #include<string.h>
                                    char* lirefichier(int* pointeurdunumchoisi);
                                    int main()
                                    {
                                        int numchoisi=7;
                                    
                                        printf("%s",lirefichier(&numchoisi));
                                    
                                        return 0;
                                    }
                                    char* lirefichier(int* pointeurdunumchoisi)
                                    {
                                        FILE* file=NULL;
                                        char mot[100]={0};
                                        int k=0;
                                        int numchoisi=0;
                                        char caractere;
                                        file=fopen("FILE.txt","r");
                                    
                                    
                                        if(file==NULL)
                                            {
                                                printf("on ne peut pas ouvrir le fichier");
                                                return 0;
                                            }
                                            else
                                                {
                                                            rewind(file);
                                                            while(caractere!=EOF)
                                                            {
                                                            caractere=fgetc(file);
                                                            if(caractere=='\n')
                                                            {
                                                               k++;
                                                            }
                                                            }
                                    
                                                            rewind(file);
                                                            numchoisi=*pointeurdunumchoisi;
                                                            while(numchoisi>0)
                                                            {
                                                                caractere=fgetc(file);
                                                                if(caractere=='\n')
                                                                    numchoisi--;
                                    
                                                            }
                                    
                                                           fgets(mot,100,file);
                                                            mot[strlen(mot)-1]='\0';
                                    
                                                        }
                                    
                                    
                                    
                                                fclose(file);
                                                return mot ;
                                    
                                               }

                                    -
                                    Edité par NouhaylaZakaria 3 septembre 2021 à 19:26:10

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      3 septembre 2021 à 19:49:18

                                      Tu devrais t'en tenir à ton idée de départ, ne pas mettre de paramètre à lirefichier()
                                      (moi j'aurais mis le nom du fichier à lire)
                                      Dans le main, tu déclares et assigne:
                                      char *motMystere = lirefichier();
                                      et tu le cherches ensuite ...
                                      tu devras faire un free(motMystere) dans le main à la fin.
                                      Dans la fonction lirefichier(), si tu ne veut pas t'embêter avec la longueur maximum, réserves mot avec malloc.
                                      char *mot = malloc(100);
                                      C'est la seule façon (ou presque ...) de retourner facilement le mot trouvé au main.
                                      numchoisi doit être déterminé avec rand()
                                      Fais:
                                      srand(time(NULL));   // avec un #include <time.h>
                                      numchoisi = (rand() * RAND_MAX) % nombredemots;
                                      • Partager sur Facebook
                                      • Partager sur Twitter

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

                                        3 septembre 2021 à 20:50:01

                                        merci infiniment finalement le code a marché et j 'ai combiné les deux codes précédents ,si je veux ameliorer le jeu en dessinant un bonhomme qui se fait pendre,comment y faire car je n'ai aucune idéé sur le dessin en language c,sinon voila le code final
                                        #include <stdio.h>
                                        #include <stdlib.h>
                                        #include <ctype.h>
                                        #include <string.h>
                                        
                                        
                                         char lireCaractere();
                                         char* lirefichier();
                                        int main()
                                        {
                                            int k=0;
                                            char* motmystere=malloc(100);
                                            motmystere=lirefichier();
                                            char* mot=malloc(strlen(motmystere));
                                            for(int g=0;g<strlen(motmystere);g++)
                                            {
                                                mot[g]='*';
                                            }
                                        
                                            while ((strcmp(mot,motmystere)!=0&&k<10))
                                            {
                                        
                                            int maLettre;
                                        
                                            maLettre = lireCaractere();
                                        
                                            for(int i=0;i<strlen(motmystere);i++)
                                            {
                                               if(maLettre==motmystere[i])
                                               {
                                                   mot[i]=maLettre;
                                                   printf("%s\n",mot);
                                        
                                               }
                                        
                                        
                                            }
                                        
                                            if (strchr(motmystere,maLettre)==NULL)
                                               {
                                        
                                                k++;}
                                        }
                                                if(strcmp(mot,motmystere)==0)
                                                {
                                        
                                                 printf("vs avez trouvez le mot");
                                                 }
                                                 else
                                                {
                                                    printf("malheureusement vs n avez pas trouve le mot");
                                                }
                                                printf("%s",motmystere);
                                        
                                            return 0;
                                        }
                                          char lireCaractere()
                                        {
                                            char caractere = 0;
                                        
                                            caractere = getchar(); // On lit le premier caractère
                                            caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
                                        
                                            // On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
                                            while (getchar() != '\n') ;
                                        
                                            return caractere; // On retourne le premier caractère qu'on a lu
                                        }
                                        char* lirefichier()
                                        {
                                            FILE* file=NULL;
                                        
                                            int k=0;
                                            int numchoisi=0;
                                            char caractere;
                                            char* mot=malloc(100);
                                            file=fopen("kkzfz.txt","r");
                                        
                                        
                                            if(file==NULL)
                                                {
                                                    printf("on ne peut pas ouvrir le fichier");
                                                    return 0;
                                                }
                                                else
                                                    {
                                                                rewind(file);
                                                                while(caractere!=EOF)
                                                                {
                                                                caractere=fgetc(file);
                                                                if(caractere=='\n')
                                                                {
                                                                   k++;
                                                                }
                                                                }
                                        
                                                                rewind(file);
                                                                srand(time(NULL));
                                                                numchoisi=rand()%k;
                                        
                                                                while(numchoisi>0)
                                                                {
                                                                    caractere=fgetc(file);
                                                                    if(caractere=='\n')
                                                                        numchoisi--;
                                        
                                                                }
                                        
                                                               fgets(mot,100,file);
                                                                mot[strlen(mot)-1]='\0';
                                        
                                                            }
                                        
                                        
                                        
                                                    fclose(file);
                                                    return mot ;
                                        
                                                   }

                                        -
                                        Edité par NouhaylaZakaria 3 septembre 2021 à 21:53:06

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          3 septembre 2021 à 22:17:57

                                          rouIoude a écrit:

                                          NouhaylaZakaria a écrit:

                                          donc on doit faire une allocation dynamique.N ' est ce pas?

                                          Tu peux, mais ce n'est pas une obligation, tu pourrais utiliser un tableau suffisamment grand pour contenir le plus grand mot existant.

                                          C'est ça que je ferais, car ça a un sens de définir une taille maximale. On sait que le plus grand mot du dictionnaire a 27 lettres ( http://www.sinotables.com/2019/11/13/voici-le-nouveau-mot-le-plus-long-de-la-langue-francaise/ ), on va donc définir :

                                          #define MAXMOT 28    // 28 à cause du caractère nul terminal
                                          /* ... ... ... ... */
                                          char motsecret[MAXMOT];

                                          ou directement

                                          char motsecret[28];

                                          si on n'a pas encore vu les #define.

                                          J'en profite pour dire que je n'aime pas qu'un cours adapté aux débutants encourage trop souvent la syntaxe :

                                          char* motsecret=/* quelque chose */;

                                          Oui elle est (en général) correcte, mais l'utilise-t-on à bon escient ? Je me souviens quand j'avais suivi le cours j'avais tendance à utiliser cette syntaxe parce qu'elle est utilisée dans le cours. Peut-être que je suis moins intelligent que la moyenne, mais au début, quand j'essayais de manipuler des chaînes de caractères définies ainsi, je me faisais avoir avec ce genre de piège :

                                          char* motsecret1={0};      // piège : du coup le mot ne comporte qu'un caractère
                                          char* motsecret2="machin"; // piège : du coup on ne peut plus le modifier

                                          Pour moi, et surtout avec un langage difficile comme le C, il faut toujours savoir ce qu'on fait au moment où on le fait. Quand on déclare une chaîne de caractères avec [] ou avec *, il faut savoir pourquoi. Ici ça a un sens de le faire avec [] et une taille constante, alors que dans une fonction, le paramètre sera déclaré avec * parce qu'il y a une raison précise à ça. Ce n'est pas juste : dans le cours ils font comme ça, alors je fais pareil. En se forçant à savoir ce qu'on fait au moment où on le fait, on évite les pièges de débutants. En tout cas c'est mon expérience. Il est vrai que je ne suis toujours pas à l'aise avec les pointeurs en général. N'empêche que programmer en C ne me fait pas peur : je fais attention à ce que je fait.

                                          (Je dis ça juste pour exprimer une opinion.)

                                          -
                                          Edité par robun 3 septembre 2021 à 22:19:21

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            4 septembre 2021 à 1:36:16

                                            Dans le main, on a les lignes:
                                             char* motmystere=malloc(100);
                                                motmystere=lirefichier();
                                               Dans lirefichier(), tu réserves de l'espace pour le mot mystère (variable mot).
                                            Tu réserves de l'espace inutilement dans le main.
                                            Tu ne fais pas de free des espaces que tu réserves avec malloc.
                                            Tu fais dans le main:
                                             char* mot=malloc(strlen(motmystere));
                                            Tu ne réserves pas d'espace pour la fin de chaîne ('\0'). Ça pourrait te causer des problèmes.  
                                            Tu remplis le mot avec des '*' mais tu ne mets pas de '\0' (fin de chaîne) à la fin.
                                            Tu es peut-être chanceux, mais il ne faut pas présumer que l'espace réservé par malloc est initialisé à 0.
                                            Si tu ne réussis pas à ouvrir le fichier, tu fais un return 0. Je t'invite à tester avec un fichier qui n'existe pas ...
                                            Tu devrais plutôt faire exit(1);
                                            Quand tu lis le fichier pour la deuxième fois, tu utilises encore des fgetc(). Tu pourrais accélérer en faisant des fgets() toujours dans le même espace
                                                while(numchoisi >= 0) {
                                                    fgets(mot,100,file);
                                                    numchoisi--;
                                                }                      
                                            Pas besoin de le refaire en dehors de la boucle, le dernier est déjà là.
                                            Pour le dessin du pendu, je pense qu'il faudra attendre encore quelques chapitres ...
                                            -
                                            > Tu peux, mais ce n'est pas une obligation, tu pourrais utiliser un tableau suffisamment grand pour contenir le plus grand mot existant.
                                            Ça ne nous dis pas où ni comment on doit réserver. Je préfère avec malloc.
                                            On pourrait le faire avec un tableau global
                                            ou un tableau statiqque dans la fonction
                                            ou un tableau réservé par malloc et passé en paramètre à la fonction.
                                            ou bêtement déclaré dans le main et passé à la fonction en paramètre
                                            ou bien ...t
                                            • Partager sur Facebook
                                            • Partager sur Twitter

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

                                              4 septembre 2021 à 14:43:18

                                              merci@robun pour tes conseils

                                              robun a écrit:

                                              rouIoude a écrit:

                                              NouhaylaZakaria a écrit:

                                              donc on doit faire une allocation dynamique.N ' est ce pas?

                                              Tu peux, mais ce n'est pas une obligation, tu pourrais utiliser un tableau suffisamment grand pour contenir le plus grand mot existant.

                                              C'est ça que je ferais, car ça a un sens de définir une taille maximale. On sait que le plus grand mot du dictionnaire a 27 lettres ( http://www.sinotables.com/2019/11/13/voici-le-nouveau-mot-le-plus-long-de-la-langue-francaise/ ), on va donc définir :

                                              #define MAXMOT 28    // 28 à cause du caractère nul terminal
                                              /* ... ... ... ... */
                                              char motsecret[MAXMOT];

                                              ou directement

                                              char motsecret[28];

                                              si on n'a pas encore vu les #define.

                                              J'en profite pour dire que je n'aime pas qu'un cours adapté aux débutants encourage trop souvent la syntaxe :

                                              char* motsecret=/* quelque chose */;

                                              Oui elle est (en général) correcte, mais l'utilise-t-on à bon escient ? Je me souviens quand j'avais suivi le cours j'avais tendance à utiliser cette syntaxe parce qu'elle est utilisée dans le cours. Peut-être que je suis moins intelligent que la moyenne, mais au début, quand j'essayais de manipuler des chaînes de caractères définies ainsi, je me faisais avoir avec ce genre de piège :

                                              char* motsecret1={0};      // piège : du coup le mot ne comporte qu'un caractère
                                              char* motsecret2="machin"; // piège : du coup on ne peut plus le modifier

                                              Pour moi, et surtout avec un langage difficile comme le C, il faut toujours savoir ce qu'on fait au moment où on le fait. Quand on déclare une chaîne de caractères avec [] ou avec *, il faut savoir pourquoi. Ici ça a un sens de le faire avec [] et une taille constante, alors que dans une fonction, le paramètre sera déclaré avec * parce qu'il y a une raison précise à ça. Ce n'est pas juste : dans le cours ils font comme ça, alors je fais pareil. En se forçant à savoir ce qu'on fait au moment où on le fait, on évite les pièges de débutants. En tout cas c'est mon expérience. Il est vrai que je ne suis toujours pas à l'aise avec les pointeurs en général. N'empêche que programmer en C ne me fait pas peur : je fais attention à ce que je fait.

                                              (Je dis ça juste pour exprimer une opinion.)

                                              -
                                              Edité par robun il y a environ 14 heures

                                               merci @robun  pour tes conseils

                                              merci @pierrelefou pour tes conseils mais est ce que tu peux m'expliquer pourquoi je dois faire exit(1) au lieu de return(0) sinon voici le code avec les modifications que tu m'as proposees

                                              #include <stdio.h>
                                              #include <stdlib.h>
                                              #include <ctype.h>
                                              #include <string.h>
                                              #include <time.h>
                                              
                                               char lireCaractere();
                                               char* lirefichier();
                                              int main()
                                              {
                                                  int k=0;
                                                  int nbredelettres;
                                                  char* motmystere;
                                                  motmystere=lirefichier();
                                                  char* mot=malloc(strlen(motmystere)+1);
                                                  for(int g=0;g<strlen(motmystere);g++)
                                                  {
                                                      mot[g]='*';
                                                  }
                                                  mot[strlen(motmystere)]='\0';
                                                  nbredelettres=strlen(motmystere);
                                                  printf("le mot a %d lettres",nbredelettres);
                                              
                                                  while ((strcmp(mot,motmystere)!=0&&k<10))
                                                  {
                                              
                                                  int maLettre;
                                              
                                                  maLettre = lireCaractere();
                                              
                                                  for(int i=0;i<strlen(motmystere);i++)
                                                  {
                                                     if(maLettre==motmystere[i])
                                                     {
                                                         mot[i]=maLettre;
                                                         printf("%s\n",mot);
                                              
                                                     }
                                              
                                              
                                                  }
                                              
                                                  if (strchr(motmystere,maLettre)==NULL)
                                                     {
                                              
                                                      k++;}
                                              }
                                                      if(strcmp(mot,motmystere)==0)
                                                      {
                                              
                                                       printf("vs avez trouvez le mot");
                                                       }
                                                       else
                                                      {
                                                          printf("malheureusement vs n avez pas trouve le mot");
                                                      }
                                                      printf("%s",motmystere);
                                              
                                                  return 0;
                                              }
                                                char lireCaractere()
                                              {
                                                  char caractere = 0;
                                              
                                                  caractere = getchar(); // On lit le premier caractère
                                                  caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
                                              
                                                  // On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
                                                  while (getchar() != '\n') ;
                                              
                                                  return caractere; // On retourne le premier caractère qu'on a lu
                                              }
                                              char* lirefichier()
                                              {
                                                  FILE* file=NULL;
                                              
                                                  int k=0;
                                                  int numchoisi=0;
                                                  char caractere;
                                                  char* mot=malloc(100);
                                                  file=fopen("kkzfz.txt","r");
                                              
                                              
                                                  if(file==NULL)
                                                      {
                                                          printf("on ne peut pas ouvrir le fichier");
                                                          exit(1);
                                                      }
                                                      else
                                                          {
                                                                      rewind(file);
                                                                      while(caractere!=EOF)
                                                                      {
                                                                      caractere=fgetc(file);
                                                                      if(caractere=='\n')
                                                                      {
                                                                         k++;
                                                                      }
                                                                      }
                                              
                                                                      rewind(file);
                                                                      srand(time(NULL));
                                                                      numchoisi=rand()%k;
                                              
                                                                      while(numchoisi>0)
                                                                      {
                                                                          fgets(mot,100,file);
                                                                           mot[strlen(mot)-1]='\0';
                                                                              numchoisi--;
                                              
                                                                      }
                                              
                                              
                                              
                                                                  }
                                              
                                              
                                              
                                                          fclose(file);
                                                          return mot ;
                                              
                                                         }
                                              




                                              -
                                              Edité par NouhaylaZakaria 4 septembre 2021 à 20:51:30

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                4 septembre 2021 à 15:15:23

                                                Dans la ligne:
                                                    char* mot=malloc(strlen(motmystere));
                                                Tu ne réserves pas un espace pour le '\0'. Il faut réserver un espace de plus.
                                                Pourquoi le exit(1) si on ne peut pas ouvrir le fichier?
                                                Le return dans le main retourne au système.
                                                Mais le return dans la fonction retourne au main, là où tu t'attends à un pointeur vers le mot mystère. C'est comme si tu retournais un pointeur NULL.
                                                Tu auras une erreur du genre "segmentation fault"
                                                Le exit(1) retourne directement au système.
                                                • Partager sur Facebook
                                                • Partager sur Twitter

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

                                                  4 septembre 2021 à 16:19:43

                                                  merci pour les explications

                                                  pour le\0

                                                  j'ai resreve de l'espace pour \0 dans la ligne20 

                                                  Dans le cours on a utilisé exit(0).est ce qu 'il y a une difference entre exit(0) et exit(1)

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    4 septembre 2021 à 18:13:20

                                                    Tu mets bien un '\0' dans la dernière position, mais tu ne la réserves pas:
                                                         char* mot=malloc(strlen(motmystere) + 1);   // c'est le +1 qui te manques.
                                                    Le exit() retourne un code au système qui peut être vérifié par ce dernier ou par des commandes exécutées en batch.
                                                    exit(0) indique qu'il n'y a pas d'erreur. exit(1) retourne le code d'erreur 1.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

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

                                                      4 septembre 2021 à 20:53:57

                                                      ah je vois maintenant la difference

                                                      ok merci beaucoup pour ton aide ^^

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        4 septembre 2021 à 21:07:45

                                                        rapidement en passant :

                                                        pour que ce soit plus facilement lisible on peut utiliser les macros EXIT_SUCCESS et EXIT_FAILURE en lieu et place de 0 et 1 … c'est même un peu plus portable. Elles sont définies dans le header stdlib.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          4 septembre 2021 à 21:28:07

                                                          @whitecrow donc EXIT_SUCCESS c'est l'equivalent de exit (0 )?et EXIT_FAILURE c'est l'equivalent de exit(1) ?

                                                          sinon merci pour l'information.

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            4 septembre 2021 à 23:09:50

                                                            oui, du moins sur les plateformes usuelles. Elles peuvent avoir d'autres valeurs sur des plateformes plus exotiques.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            tp jeu pendu (language c partie 2)

                                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                            • Editeur
                                                            • Markdown