Partage
  • Partager sur Facebook
  • Partager sur Twitter

Je bloque sur le TP du pendu avec dictionnaire

Le tp se trouvant dans le cours sur le language c de mateo

    9 septembre 2021 à 17:43:21

    Je n'arrive pas a compiler mon projet et ça fait plusieurs jours maintenant que j'y réfléchit.Oui j'ai finit par copier coller le code de mateo, j'en suis pas fier mais ce tp m'a poser quelques difficultés.

    Voici mon main

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    #include "dico.h"
    
    int gagne(int lettreTrouvee[], long tailleMot);
    int rechercheLettre(char lettre, char motSecret[], int lettreTrouvee[]);
    char lireCaractere();
    
    
    int main()
    {
        char lettre = 0; 
        char motSecret[100] = {0}; 
        int *lettreTrouvee = NULL;  
        long coupsRestants = 10; 
        long i = 0; 
        long tailleMot = 0;
    
        printf("Bienvenue dans le Pendu !\n\n");
    
        if (!(piocherMot(motSecret)))
            exit(0);
    
        tailleMot = strlen(motSecret);
    
        lettreTrouvee = malloc(tailleMot * sizeof(int)); 
        if (lettreTrouvee == NULL)
            exit(0);
    
        for (i = 0 ; i < tailleMot ; i++)
            lettreTrouvee[i] = 0;
    
       
        while (coupsRestants > 0 && !gagne(lettreTrouvee, tailleMot))
        {
            printf("\n\nIl vous reste %ld coups a jouer", coupsRestants);
            printf("\nQuel est le mot secret ? ");
    
            
            for (i = 0 ; i < tailleMot ; i++)
            {
                if (lettreTrouvee[i]) 
                    printf("%c", motSecret[i]); 
                else
                    printf("*"); 
            }
    
            printf("\nProposez une lettre : ");
            lettre = lireCaractere();
    
            
            if (!rechercheLettre(lettre, motSecret, lettreTrouvee))
            {
                coupsRestants--; 
            }
        }
    
        if (gagne(lettreTrouvee, tailleMot))
            printf("\n\nGagne ! Le mot secret etait bien : %s", motSecret);
        else
            printf("\n\nPerdu ! Le mot secret etait : %s", motSecret);
    
        free(lettreTrouvee); 
    
            return 0;
    }
    
    char lireCaractere()
    {
        char caractere = 0;
    
        caractere = getchar(); 
        caractere = toupper(caractere); 
    
        
        while (getchar() != '\n') ;
    
        return caractere; 
    }
    
    int gagne(int lettreTrouvee[], long tailleMot)
    {
        long i = 0;
        int joueurGagne = 1;
    
        for (i = 0 ; i < tailleMot ; i++)
        {
            if (lettreTrouvee[i] == 0)
                joueurGagne = 0;
        }
    
        return joueurGagne;
    }
    
    int rechercheLettre(char lettre, char motSecret[], int lettreTrouvee[])
    {
        long i = 0;
        int bonneLettre = 0;
    
        
        for (i = 0 ; motSecret[i] != '\0' ; i++)
        {
            if (lettre == motSecret[i]) 
            {
                bonneLettre = 1; 
                lettreTrouvee[i] = 1; 
            }
        }
    
        return bonneLettre;
    }

    mon dico.c

    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    #include "dico.h"
    
    int nombreAleatoire(int nombreMax)
    {
        srand(time(NULL));
        return (rand() % nombreMax);
    }
    
    
    int piocherMot(char *motPioche)
    {
      FILE *dico=NULL;
      int i=0,  nombreMot=0, numMotChoisi=0;
      int caractereLu=0;
    
      dico=fopen("dico.txt","r");
      if (dico==NULL)
      {
          printf("\nImpossible de charger le dictionnaire de mots");
          return 0;
      }
      do
      {
          caractereLu=fgetc(dico);
          if(caractereLu=='\n')
          {
              nombreMot++;
          }
      } while (caractereLu!=EOF);
    
      
      
      
      numMotChoisi=nombreAleatoire(nombreMot);
      rewind(dico);
      while(numMotChoisi>0)
      {
          caractereLu=fgetc(dico);
          if (caractereLu=='\n')
          {
              numMotChoisi--;
          }
      }
    fgets(motPioche,100,dico);
    motPioche[strlen(motPioche)-1]='\0';
    fclose(dico);
    return 1;
      
      
    }
    
    

    et enfin mon dico.h

    #ifndef DEF_DICO
    #define DEF_DICO
    
    int piocherMot(char *motPioche);
    int nombreAleatoire(int nombreMax);
    
    #endif

    quand jexecute mon main j'obtient cette erreur:

    Undefined symbols for architecture arm64:
    "_piocherMot", referenced from:
    _main in main-7457b2.o
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    et je ne comprend pas... j'ai bien inclus le dico.h et mes fichiers sont bien dans le meme dossier. Merci beaucoup pour une éventuelle aide et je tiens a préciser que je suis sur macos avec processeur M1 et je code sur VS code. 


    -
    Edité par Restitutor_Orbis 9 septembre 2021 à 17:51:00

    • Partager sur Facebook
    • Partager sur Twitter
      9 septembre 2021 à 18:37:36

      Je ne connais pas VS Code, mais quand on construit un projet multi fichiers, il faut compiler tout les fichiers sources, or il semblerais que tu ne compiles pas le fichier dico.c et ou tu ne lies pas le fichier objet issus de la compilation de ce même fichier.

      Il faut donc regarder dans la doc de ton EDI comment on ajoute ce fichier à ton projet.

      • Partager sur Facebook
      • Partager sur Twitter
      ...
        9 septembre 2021 à 19:39:34

        Je ne suis pas non plus sur un Mac et je n'ai pas d'IDE comme VS Code ...
        D'accord avec la suggestion de RouIoude.
        Si tu te crois capable de le faire:
        Lors de la première lecture, détermine la longueur du mot le plus long.
        Lors de la seconde lecture, fais des fgets directement dans ton espace de sortie )motPioche) de la longueur + 1
        Cela ira plus rapidement. Tu ne fais pas de fgets() après la boucle while
        Tu devras changer le test:
          while(numMotChoisi>=0)   «// >= au lieu de >
        Pourquoi utiliser des 'long' au lieu de 'int'?
        Quelle est la longueur de ton dictionnaire?
        rand() retourne un nombre entre 0 et 32767
        Je te suggère de faire:
        (rand() * 32767) % nombreMax;
        • Partager sur Facebook
        • Partager sur Twitter

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

          13 septembre 2021 à 1:59:10

          PierrotLeFou a écrit:

          Je ne suis pas non plus sur un Mac et je n'ai pas d'IDE comme VS Code ...
          D'accord avec la suggestion de RouIoude.
          Si tu te crois capable de le faire:
          Lors de la première lecture, détermine la longueur du mot le plus long.
          Lors de la seconde lecture, fais des fgets directement dans ton espace de sortie )motPioche) de la longueur + 1
          Cela ira plus rapidement. Tu ne fais pas de fgets() après la boucle while
          Tu devras changer le test:
            while(numMotChoisi>=0)   «// >= au lieu de >
          Pourquoi utiliser des 'long' au lieu de 'int'?
          Quelle est la longueur de ton dictionnaire?
          rand() retourne un nombre entre 0 et 32767
          Je te suggère de faire:
          (rand() * 32767) % nombreMax;

          rouIoude a écrit:

          Je ne connais pas VS Code, mais quand on construit un projet multi fichiers, il faut compiler tout les fichiers sources, or il semblerais que tu ne compiles pas le fichier dico.c et ou tu ne lies pas le fichier objet issus de la compilation de ce même fichier.

          Il faut donc regarder dans la doc de ton EDI comment on ajoute ce fichier à ton projet.


          Merci pour votre aide, désolé du retard j'ai eu quelques empêchements... J'avais déjà penser a compiler le dico.c mais la aussi j'ai un problème dans la compilation. J'ai donc tout mis dans un seul fichier et ça marche! Par contre je ne vois toujours pas pourquoi ça ne marchait pas quand j’étais en multifichiers...

           

          -
          Edité par Restitutor_Orbis 13 septembre 2021 à 2:05:19

          • Partager sur Facebook
          • Partager sur Twitter
            13 septembre 2021 à 2:57:13

            @Restitutor_Orbis Bonsoir, je viens de retirer des spams votre dernier message, si cela arrive encore vous pouvez poster dans ce sujet Si votre message est considéré comme spam

            • Partager sur Facebook
            • Partager sur Twitter
              13 septembre 2021 à 8:39:32

              Restitutor_Orbis a écrit:

              J'ai donc tout mis dans un seul fichier et ça marche! Par contre je ne vois toujours pas pourquoi ça ne marchait pas quand j’étais en multifichiers...

              Parce que tu n'as pas mis le fichier dico.c dans ton projet.

              dico.c doit être compilé et le fichier objet résultant de la compilation dico.o doit être lié lors de la production de l'exécutable.

              • Partager sur Facebook
              • Partager sur Twitter
              ...
                13 septembre 2021 à 18:36:40

                Mais comment fait-on avec VS code? Ça se faitt bien en invite de commande (ce que je fais)
                Ne faut-il pas une option pour dire quels fichiers doivent être compilés et liés (linked).
                • Partager sur Facebook
                • Partager sur Twitter

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

                  18 septembre 2021 à 12:36:52

                  rouIoude a écrit:

                  Restitutor_Orbis a écrit:

                  J'ai donc tout mis dans un seul fichier et ça marche! Par contre je ne vois toujours pas pourquoi ça ne marchait pas quand j’étais en multifichiers...

                  Parce que tu n'as pas mis le fichier dico.c dans ton projet.

                  dico.c doit être compilé et le fichier objet résultant de la compilation dico.o doit être lié lors de la production de l'exécutable.

                  Svp vous pouvez me dire comment on fait sur VS code?

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Je bloque sur le TP du pendu avec dictionnaire

                  × 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