Partage
  • Partager sur Facebook
  • Partager sur Twitter

Initialisation d'un tableau de structure en C

    19 octobre 2017 à 17:27:24

    Bonjour à tous, pour un projet je dois coder un agenda, j'ai un petit peu avancé mais cela fais déjà 3 jours que je bloque sur une initialisation de structure.

    Voila ma fonction qui initialse tous les paramètres de ma structure à 0 

    void initialiseTableauRDV(RdV *rendezvous)
    {
        int i,j;
    
    
        for (i=0; i<NBMAX_RDV; i++)
        {
            (*rendezvous).date.jour = NULL;
            (*rendezvous).date.mois = 0;
            (*rendezvous).date.annee = 0;
            (*rendezvous).horaireDeb.heure = 0;
            (*rendezvous).horaireDeb.minute = 0;
            (*rendezvous).horaireFin.heure = 0;
            (*rendezvous).horaireFin.minute = 0;
                for (j=0; j<LGMAX_LIBEL; j++)
        {
            rendezvous[i].libele[j] = '\0';
        }
            //rendezvous[i].libele[1] = '0';
                    printf("RDV %d/%d/%d %dh%d - %dh%d \n    %s",(*rendezvous).date.jour, (*rendezvous).date.mois, (*rendezvous).date.annee, (*rendezvous).horaireDeb.heure, (*rendezvous).horaireDeb.minute, (*rendezvous).horaireFin.heure, (*rendezvous).horaireFin.minute, rendezvous[i].libele);
    printf("\n");
        }
    
    }

    Ma fonction initialise bien mon tableau de structure, je le vois grâce au printf, mon problème est que lorsque je relis les paramètres sensés avoir été passés à 0 dans une autre fonction, ce ne sont plus les mêmes, le tableau que j’initialise et celui que lit ensuite sont différent, l'un doit être la copie de l'autre, voila mon main : 

    int main()
    {
        RdV rendezvous[NBMAX_RDV];
        initialiseTableauRDV(&rendezvous);
        menu1(&rendezvous);
        return 0;
    }


    Ma fonction menu1 appelle une foction nomée traiterChoixAjouterRDV et c'est dans celle-ci que je souhaite lire les valeurs des cases de mon tableau pour ensuite savoir quelles cases sont libres et lesquelles ne le sont pas, voici sa defintion :

    void traiterChoixAjouterRDV(RdV *rendezvous)
    {
        int i;
            for(i=0; rendezvous[i].date.jour != 0; i++)
            {
                    printf("RDV %d/%d/%d %dh%d - %dh%d \n    %s",rendezvous[i].date.jour, rendezvous[i].date.mois, rendezvous[i].date.annee, rendezvous[i].horaireDeb.heure, rendezvous[i].horaireDeb.minute, rendezvous[i].horaireFin.heure, rendezvous[i].horaireFin.minute, rendezvous[i].libele);
    
            } //Instruction vide pour arriver a la premiere case libre
     printf("RDV %d/%d/%d %dh%d - %dh%d \n    %s",(*rendezvous).date.jour, (*rendezvous).date.mois, (*rendezvous).date.annee, (*rendezvous).horaireDeb.heure, (*rendezvous).horaireDeb.minute, (*rendezvous).horaireFin.heure, (*rendezvous).horaireFin.minute, rendezvous[i].libele);
    printf("\n");
        //int test;
        printf("\nEn entrant dans la fonciton le nb de rdv est de %d\n", i);
        printf("----------------------------------\n");
        printf("----------AJOUTER RDV-----------\n");
        printf("----------------------------------\n");
        printf("Entrez le rendez-vous sous la forme suivante :\nJJ/MM/AAAA HeureDebut - HeureFin\n");
        scanf(" %d/%d/%d %d h %d - %d h %d",&rendezvous[i].date.jour, &rendezvous[i].date.mois, &rendezvous[i].date.annee, &rendezvous[i].horaireDeb.heure, &rendezvous[i].horaireDeb.minute, &rendezvous[i].horaireFin.heure, &rendezvous[i].horaireFin.minute);
        printf("\nEntrez Maintenant le libelle de ce rendez vous : ");
        viderBuffer(); //On purge le buffer
        fgets( rendezvous[i].libele, LGMAX_LIBEL, stdin); //Utilisation de fgets pour recuperer une phrase, la fonciton scanf s'arrette au premier espace rencontré
        printf("Votre rendez-vous a ete ajoute !\n");
        //printf("RDV %d/%d/%d %dh%d - %dh%d \n    %s",rendezvous[i].date.jour, rendezvous[i].date.mois, rendezvous[i].date.annee, rendezvous[i].horaireDeb.heure, rendezvous[i].horaireDeb.minute, rendezvous[i].horaireFin.heure, rendezvous[i].horaireFin.minute, rendezvous[i].libele);
    
        for(i=0; rendezvous[i].date.jour != 0; i++)
        {
            printf("RDV %d/%d/%d %dh%d - %dh%d \n    %s",rendezvous[i].date.jour, rendezvous[i].date.mois, rendezvous[i].date.annee, rendezvous[i].horaireDeb.heure, rendezvous[i].horaireDeb.minute, rendezvous[i].horaireFin.heure, rendezvous[i].horaireFin.minute, rendezvous[i].libele);
        }
        printf("En sortant de la fonciton le nb de rdv est de %d", i);
        menu2(&rendezvous);
    }
    

    J'ai placé quelques lignes de test pour tenter de debugger mon programme mais rien y fait, je suis comlpèteùent bloqué, s'y quelqu'un aurait un peu de temps ça serai vraiement sympa, j'ai déjà lu tous les articles possible mais je n'ai pas trouvé de solution à mopn problème.

    Jeremy



    • Partager sur Facebook
    • Partager sur Twitter
      19 octobre 2017 à 17:39:48

      Salut,

      Tout d'abord,les deux lignes ci-dessous sont équivalentes

      (*rendezvous).date.jour = NULL;
      rendezvous->date.jour = NULL;

      En effet, on n'écrit jamais comme la première ligne, et toujours comme la deuxième.

      Ensuite, c'est faux dans ton cas, car ta fonction ne reçoit pas un pointeur sur Rdv, mais un tableau de Rdv (en fait c'est la même chose, mais la sémantique est différente).

      Ce qui veux dire qu'il faut initialiser chaque case de ce tableau dans ton for :

      for(i = 0; i < NBMAX_RDV; i++) {
          rendezvous[i].date.jour = NULL;
          // ...
      }

      Je n'ai pas trop regardé la suite, mais corrige déjà ça

      -
      Edité par Smiley32 19 octobre 2017 à 17:40:32

      • Partager sur Facebook
      • Partager sur Twitter

      J'aime les bandes dessinées, manhuas, manhwas, mangas, comics... Du coup j'ai fait aralosbd.fr !

        19 octobre 2017 à 17:47:39

        Salut Jeremy,

        Alors c'est bien d'initialiser ta structure mais tu as un fonction toute mignonne qui le fait pour toi :) memset()

        un petit exemple d'utilisation :

        #include <stdlib.h>
        #include <string.h>
        typedef struct  example
        {
            char *name;
            char tab[50];
            int nbr;
        }t_example;
        
        int main()
        {
            t_example *example;
        
            example = malloc(sizeof(t_example));
            if (example == NULL)
                return EXIT_FAILURE;
            example = memset(example, 0, sizeof(t_example));
            if (example == NULL)
                return EXIT_FAILURE;
            return EXIT_SUCCESS;
        }

        Essaye avec ça ;)

        -
        Edité par NutNut tu coco 19 octobre 2017 à 17:50:33

        • Partager sur Facebook
        • Partager sur Twitter
        Quand tu regardes l'abîme, l'abîme regarde aussi en toi.
          20 octobre 2017 à 17:34:42

          Merci Smiley et Nutnut, désolé j'avais pas vu votre réponse, 

          Smiley j'ai corrigé, j'avais déjà essayé comme ceci avant mais le problème reste identique, au début de ma fonction avec le printf (dans ma fonction d’initialisation) je vois bien que mon tableau (ou du moins la copie de mon tableau je suppose) est bien initialisée, voici ce qui s'affiche :

              RDV 0/0/0 0h0 - 0h0
              RDV 0/0/0 0h0 - 0h0
              RDV 0/0/0 0h0 - 0h0

          Mais lorsque ma fonction suivante vérifie qu'elle peut écrire à une ligne donnée tu tableau, j'ai refais un printf pour voir le contenu de cette ligne du tableau à ce moment là et voici ce qu'il s'affiche : 

          RDV 6395920/1955997192/4199252 6395868h1955738410 - 6422476h4
              îÆò:■   8£aRDV 6395920/1955997192/4199252 6395868h1955738410 - 6422476h4

          Je pense que je n'arrive pas à bien passer mon tableau de structure en paramètre, je dois m’emmêler avec les pointeurs, adresses, tableaux etc.., j'ai essayé plein de combinaisons différentes en espérant trouver quelque chose qui fonctionne mais en vain.

          Nutnut j'ai essayé ta méthode mais je n'arrive pas à la mettre en place avec un tableau, j'ai quand même tenté mais l'initilasation ne se produit pas, toutes les ligne de mon tableau sont similaires à la deuxième insertion de code dans ma réponse à Smiley32.

          Je ne sais plus trop quoi essayer, cette erreur me rend fou!

          Merci pour vos réponses en tout cas !

          • Partager sur Facebook
          • Partager sur Twitter
            20 octobre 2017 à 17:51:20

            Salut alors si tu reçois ce genre de truc c'est que tu accèdes a une partie de ta mémoire ou il a quelque chose écrite ^^ tu n'as pas décaler ton pointeur quelque part sans faire exprès ??

            Tu compiles avec quoi ? renseigne toi sur valgrind c'est un programme qui permet de débuger entre autre se style d'erreur :)

            peut tu nous donner ta stucture complète ? (je veux essayer de te montrer comment faire avec memset)

            • Partager sur Facebook
            • Partager sur Twitter
            Quand tu regardes l'abîme, l'abîme regarde aussi en toi.
              20 octobre 2017 à 22:15:55

              Voilà mon .h : 

              #ifndef FONCTIONS_H_INCLUDED
              #define FONCTIONS_H_INCLUDED
              #define NBMAX_RDV 300
              #define LGMAX_LIBEL 50
              
              
              
              #include <stdio.h>
              #include <stdlib.h>
              
              //#include "fonctions.h"
              
              //STRUCTURES//
              
              typedef struct Date Date;
              struct Date
              {
                  int jour;
                  int mois;
                  int annee;
              };
              
              typedef struct Horaire Horaire;
              struct Horaire
              {
                  int heure;
                  int minute;
              };
              
              typedef struct RdV RdV;
              struct RdV
              {
                  Date date;
                  Horaire horaireDeb, horaireFin;
                  char libele[LGMAX_LIBEL];
                  int rappel;
              };
              //extern RdV *rendezvous[NBMAX_RDV];
              //PROTOTYPES//
              
              
              //void modifierHoraire ( int duree, int h, int mn, int horaire[1][2], t_horaire *t_horaire);
              
              void choixMenu1 ( int choix1, RdV *rendezvous);
              void menu1(RdV *rendezvous);
              void choixMenu2 ( int choix2, RdV *rendezvous);
              void menu2(RdV *rendezvous);
              
              void traiterChoixCreerAgenda(RdV *rendezvous);
              void traiterChoixOuvrirAgenda();
              void traiterChoixModifierRDV();
              void traiterChoixAjouterRDV(RdV *rendezvous); //avant RdV[]
              void traiterChoixSupprimerRDV();
              void traiterChoixSupprimerTousRDV();
              void traiterChoixSauvergarderEtFermer();
              
              void initialiseTableauRDV(RdV *rendezvous);
              
              //void purger(void);
              
              #endif // FONCTIONS_H_INCLUDED
              

              Je compile avec codeblock, compiler GNU GCC.

              Je vais me renseigner sur valgrind merci pour l'info !

              • Partager sur Facebook
              • Partager sur Twitter
                21 octobre 2017 à 19:23:42

                Re,

                Ca vient sûrement du fait que tu passes mal ton tableau à ta fonction menu : il faut juste faire

                menu1(rendezvous);



                • Partager sur Facebook
                • Partager sur Twitter

                J'aime les bandes dessinées, manhuas, manhwas, mangas, comics... Du coup j'ai fait aralosbd.fr !

                  23 octobre 2017 à 9:52:06

                  Salut !! 

                  en voulant te montrer le memset j'ai trouvé ton problème ;)

                  dans ton main tu déclare un tableau de stucture :) du coup un RDV[300] ensuite tu envoie le pointeur du coup ! tu dois recevoir dans ton header ça :

                  *RDV[300] :) voili voilou :)

                  EDIT :

                  Bon ba je confirme ;)

                  Voilà comme dit ton programme initialiser avec memset :) utilise le c'est beaucoup mieux ;)

                  #include <stdlib.h>
                  #include <stdio.h>
                  #include <string.h>
                  
                  typedef struct s_date
                  {
                      int jour;
                      int mois;
                      int annee;
                  }t_date;
                   
                  typedef struct s_horaire
                  {
                      int heure;
                      int minute;
                  }t_horaire;
                   
                  typedef struct s_rdv
                  {
                      t_date *date;
                      t_horaire *horaireDeb;
                      t_horaire *horaireFin;
                      char *libele;
                      int rappel;
                  }t_rdv;
                  
                  int init_struct(t_rdv **tab_rdv)
                  {
                    int i;
                  
                    for(i = 0; i < 300; ++i) {
                      if ((tab_rdv[i] = memset(tab_rdv[i], 0, sizeof(t_rdv))) == NULL)
                        return EXIT_FAILURE;
                      if ((tab_rdv[i]->libele = malloc(sizeof(char) * (50))) == NULL)
                        return EXIT_FAILURE;
                      if (((tab_rdv[i]->date = malloc(sizeof(t_date))) == NULL)
                        || ((tab_rdv[i]->date = memset(tab_rdv[i]->date, 0, sizeof(t_date))) == NULL)
                        || ((tab_rdv[i]->horaireDeb = malloc(sizeof(t_horaire))) == NULL)
                        || ((tab_rdv[i]->horaireDeb = memset(tab_rdv[i]->horaireDeb, 0, sizeof(t_horaire))) == NULL)
                        || ((tab_rdv[i]->horaireFin = malloc(sizeof(t_horaire))) == NULL)
                        || ((tab_rdv[i]->horaireFin = memset(tab_rdv[i]->horaireFin, 0, sizeof(t_horaire))) == NULL))
                        return EXIT_FAILURE;
                    }
                    return EXIT_SUCCESS;
                  }
                  
                  void display_structure(t_rdv **tab_rdv)
                  {
                    int i = 0;
                    while (i < 3) {
                      printf("rdv : %d\n", i);
                      printf("Date :\n");
                      printf("jour : %d, mois : %d, annee; %d\n", tab_rdv[i]->date->jour, tab_rdv[i]->date->mois, tab_rdv[i]->date->annee);
                      printf("Heur debut :\n");
                      printf("heure : %d, minute : %d\n",tab_rdv[i]->horaireDeb->heure, tab_rdv[i]->horaireDeb->minute);
                      printf("Heur fin :\n");
                      printf("heure : %d, minute : %d\n",tab_rdv[i]->horaireFin->heure, tab_rdv[i]->horaireFin->minute);
                      printf("libele : %s\n", tab_rdv[i]->libele);
                      printf("rappel : %d\n\n", tab_rdv[i]->rappel);
                      ++i;
                    }
                  }
                  
                  void modif_structure(t_rdv **tab_rdv)
                  {
                    tab_rdv[0]->date->jour = 1;
                    tab_rdv[0]->date->mois = 1;
                    tab_rdv[0]->date->annee = 2018;
                    tab_rdv[0]->horaireDeb->heure = 12;
                    tab_rdv[0]->horaireDeb->minute = 0;
                    tab_rdv[0]->horaireFin->heure = 13;
                    tab_rdv[0]->horaireFin->minute = 30;
                    tab_rdv[0]->libele = "Rendez-vous raclette !";
                    tab_rdv[0]->rappel = 2;
                  }
                  
                  int main() {
                    t_rdv *tab_rdv[300];
                    int i;
                  
                    for (i = 0; i < 300; ++i) {
                      if ((tab_rdv[i] = malloc(sizeof(t_rdv))) == NULL)
                        return EXIT_FAILURE;
                    }
                    if (init_struct(tab_rdv) == EXIT_FAILURE)
                      return EXIT_FAILURE;
                    printf("\n STRUCTURE INIT \n");
                    display_structure(tab_rdv);
                    printf("\n STRUCTURE MODIF \n");
                    modif_structure(tab_rdv);
                    display_structure(tab_rdv);
                    return EXIT_SUCCESS;
                  }



                  -
                  Edité par NutNut tu coco 23 octobre 2017 à 10:25:46

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Quand tu regardes l'abîme, l'abîme regarde aussi en toi.
                    23 octobre 2017 à 11:37:26

                    Bonjour NutNut tu coco,

                    Il n'est pas utile de comparer avec NULL ce que retourne memset.
                    En outre, malloc + memset se réduit à calloc.
                    Mais la fonction memset est de bas niveau (elle travaille sur des bytes) et n'est pas idéal (pas tout à fait portable, voire carrément fausse) pour initialiser des types un peu plus compliqués que des entiers.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Initialisation d'un tableau de structure en C

                    × 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