Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème sur les Structures

Sujet résolu
    28 octobre 2019 à 12:39:35

    Bonjour,

    Je suis débutant en C et comme mon cours à l'IUT n'avance pas vraiment, j'ai décidé de prendre les devants en m'instruisant sur OC.

    Je suis actuellement le cours de Mathieu Nebra sur la programmation en C et je suis confronté à un petit problème au niveau des structures. En effet, dans le cours il est mentionné une structure Personne qui prend en paramètre un tableau (je ne sais pas si c'est clair dit comme ça, voici l'exemple donné dans le cours) :

    typedef struct Personne Personne
    struct Personne
    {
        char nom[100];
        char prenom[100];
        //j'ai raccourci un peu la structure pour n'avoir qu'à gérer le nom et le prénom d'un joueur.
    };
    Personne joueurs[2];

    Et lors de l'initialisation, il est fortement conseillé de le faire via une fonction. C'est là que je bloque. L'exemple de cours montre une fonction qui prend en paramètre une structure simple (sans tableau), mais j'aimerai de mon côté pour mieux comprendre essayer avec cette structure-ci, sans succès pour le moment. Voici mon code (qui ne m'indique pas d'erreur lors de la compilation mais qui plante à l'exécution) :

    //strucuture.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "structure.h"
    
    void initStructPersonne(Personne **pers, int taille)
    {
        for(int i = 0 ; i < taille ; i++)
        {
            *pers[i]->nom = "";
            *pers[i]->prenom = "";
        }
    }
    
    
    //structure.h
    #ifndef DEF_STRUCTURE
    #define DEF_STRUCTURE
    
    typedef struct Personne Personne;
    struct Personne
    {
        char nom[100];
        char prenom[100];
    };
    
    void initStructPersonne(Personne **pers, int taille);
    
    #endif // DEF_STRUCTURE
    
    
    //main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "../structure.h"
    
    int main()
    {
        int j = 1, i = 0, taille = 2;
        Personne joueur[taille];
    
        initStructPersonne(&joueur, taille);
    
        while (i < taille)
        {
            printf("Joueur numero %d\n", j);
            printf("Son prenom : ");
            scanf("%s", joueur[i].prenom);
            printf("Son nom : ");
            scanf("%s", joueur[i].nom);
            system("cls");
            i++;
            j++;
        }
    
        i = 0;
        j = 1;
    
        while (i < taille)
        {
            printf("Joueur numero %d : %s %s\n", j, joueur[i].prenom, joueur[i].nom);
            i++;
            j++;
        }
    
        printf("\nFin du programme.\n\n");
    
        return 0;
    }
    

    J'ai essayé, en me disant qu'un pointeur d'un tableau pourrait être représenter via un pointeur d'un pointeur, mais je crois que mon erreur se situe plus ou moins à ce niveau-là.

    Si des personnes plus compétentes que moi auraient envie de m'aider, je les en remercierai.

    • Partager sur Facebook
    • Partager sur Twitter
      28 octobre 2019 à 13:28:12

      Je crois que tu fais une confusion à cause des tableaux qui sont dans la structure.

      L'appel à la fonction d'intialisation est correct :

      initStructPersonne(&joueur, taille);


      La variable 'joueur' est de type 'Personne', c'est son adresse qui est passée en paramètre afin de pouvoir conserver les modifications sur cette variable.

      Du coup la définition de la fonction doit être :

      void initStructPersonne(Personne *pers, taille)

      Une seule étoile : c'est une adresse de 'Personne' qu'on envoie dans la fonction, pas une adresse d'adresse ! Le fait que le type 'Personne' soit composé de tableaux ou d'autres choses (par exemple de pointeurs sur des tableaux de structures d'unions de je ne sais quoi) ne change rien au fait que c'est juste l'adresse d'une 'Personne' qui est envoyée à la fonction. (En fait 'taille' est inutile, sauf si tu veux initialiser tout le tableau dans la fonction ? Dans ce cas il faudrait appeler la fonction initTableauDePersonne...)

      De plus la fonction d'initialisation n'est pas bonne. Tu initialises un tableau de 'Personne' alors que cette structure définit une seule personne. Pour initialiser un tableau de personnes :

      Personne joueur[taille] ;
      
      for (int n = 0 ; n < taille ; n++)
      {
          initPersonne(joueur[n]) ;
      }

      où la fonction initPersonne ne dépend pas de 'taille' (j'ai enlevé "struct" : on n'initialise une 'Personne'. Dedans, il y a des affectations du genre :

      strcpy(pers->nom,"") ;
      

      (et idem avec le prénom). Utiliser 'strcpy', pas '=' puisque c'est une chaîne.

      dans le cours il est mentionné une structure Personne qui prend en paramètre un tableau (je ne sais pas si c'est clair dit comme ça,

      Il ne faut pas le dire comme ça : une structure ne prend rien en paramètre, la preuve c'est qu'il n'y a pas de notation structure(paramètre). Une structure permet de définir une variable plus grosse (normalement) que les variables simples. On peut voir une structure comme un paquet d'octets un peu plus gros (composé de sous-paquets auxquels on donne un nom : 'nom' et 'prenom' par exemple).

      -
      Edité par robun 28 octobre 2019 à 13:30:55

      • Partager sur Facebook
      • Partager sur Twitter
        28 octobre 2019 à 14:08:07

        Cannapaich a écrit:

        Voici mon code (qui ne m'indique pas d'erreur lors de la compilation mais qui plante à l'exécution) 

         Pas d'erreurs, mais des warnings, faut aussi en tenir compte ! 

        Le but apparent de ta fonction est d'initialiser tout le tableau avec des chaînes vides. Comme dit robun un simple pointeur suffit comme paramètre de la fonction : 

        void initStructPersonne(Personne *pers, int taille)

        Par contre pas d' & devant le nom du tableau dans l'appel de la fonction car le nom d'un tableau seul sans les crochets renvoi l'adresse de son premier élément :

        initStructPersonne(joueur, taille);

        Aussi, pour les tableaux de char interne à la structure : on ne peut pas modifier un tableau avec l'opérateur = , pour le modifier on doit utiliser la fonction strcpy. Dans ton cas précis vu que tu veut l'initialiser en chaîne vide tu peux éventuellement mettre la première case à '\0', ce qui en fera une chaîne vide.





        • Partager sur Facebook
        • Partager sur Twitter
          28 octobre 2019 à 14:55:28

          Merci pour ces informations !

          J'ai modifié un peu mon programme avec les conseils que vous m'avez donné et maintenant tout fonctionne et j'ai compris.

          J'ai préféré la méthode de rouloude ceci dit...

          void initPersonne(Personne *pers, int taille)
          {
              for(int i = 0 ; i < taille ; i++)
              {
                  strcpy(pers[i].nom,"");
                  strcpy(pers[i].prenom,"");
              }
          }

          Merci de votre aide et bonne journée.

          -
          Edité par KANNAPÉ 28 octobre 2019 à 14:56:37

          • Partager sur Facebook
          • Partager sur Twitter

          Problème sur les Structures

          × 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