IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Exercice coriace sur les arbres binaires


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut Exercice coriace sur les arbres binaires
    Bonjour/Bonsoir Monsieur/Madame.

    Je suis confronté à un problème depuis 13 jours et je ne trouve toujours pas le solution voilà pourquoi je me tourne vers vous. Si personne ne m'aide, je crois que mon expérience
    dans le monde de la programmation C pourrait prendre un gros parpaing sur la tête. En d'autres mots, S'IL VOUS PLAIT J'AI BESOIN D'AIDE!!! Si quelqu'un a déjà traité un genre d'exercice, pourrait-il me dire juste étape par étape ce qu'il y a lieu de faire ?

    Voilà mon problème:

    1) On me donne un fichier famille.txt (voir plus bas), qui contient pour chacun des membres d'une famille, le nom du père et de la mère s'ils sont connus, 'inconnu' autrement. Ecrire un programme avec une variable famille capable de stocker les informations d'au maximum 10 personnes, et copier les données du fichier dans cette variable et si possible, les afficher.

    Voici la structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct person
    {
    	char nom[32];
    	char prenom[32];
    	int jour, mois, annee, index;
    	struct person *pere;
    	struct person *mere;
    } PersonT;
    2) Initialiser tous les champs de la structure. Si le père ou la mère sont inconnus, les champs pere et mere doivent être initialisé à NULL. Uiliser la fonction strcmp(chaine1, chaine2).

    3)Trier les membres de la famille par ordre alphabétique.

    4) Plutôt que de matérialiser les relations pere/mere, on souhaite matérialiser la relation enfants, en ajoutant dans chaque structure un tableau de pointeur vers des personnes, de la façon suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct person
    {
    	char nom[32];
    	char prenom[32];
    	int jour, mois, annee, index;
    	struct person *enfants[4];
    } PersonT;
    Écrire un programme qui lit le fichier famille.txt, et initialise tous ses champs de façon à
    pouvoir retrouver directement tous les enfants de chaque personne.

    Voilà le contenu du fichier famille.txt

    Code text : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    Johnson
    Albert
    7
    6
    1897
    inconnu
    inconnu
    inconnu
    inconnu
     
    Johnson
    Catherine
    14
    10
    1898
    inconnu
    inconnu
    inconnu
    inconnu
     
    Johnson
    Renee
    21
    7
    1924
    Johnson
    Albert
    Johnson
    Catherine
     
    Johnson
    Paul
    21
    10
    1926
    Johnson
    Albert
    Johnson
    Catherine
     
    Heyden
    Bernard
    31
    10
    1920
    inconnu
    inconnu
    inconnu
    inconnu
     
    Heyden
    Bruno
    12
    9
    1955
    Heyden
    Bernard
    Johnson
    Renee

    Merci d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 502
    Par défaut
    Bonjour,

    Puisque c'est un exercice scolaire, on va rester volontairement théoriques sans te donner de code tout fait, mais tu peux poster le tien à la suite pour qu'on te le corrige éventuellement.


    Citation Envoyé par honolyani Voir le message
    Bonjour/Bonsoir Monsieur/Madame.

    Je suis confronté à un problème depuis 13 jours et je ne trouve toujours pas le solution voilà pourquoi je me tourne vers vous. Si personne ne m'aide, je crois que mon expérience
    dans le monde de la programmation C pourrait prendre un gros parpaing sur la tête. En d'autres mots, S'IL VOUS PLAIT J'AI BESOIN D'AIDE!!! Si quelqu'un a déjà traité un genre d'exercice, pourrait-il me dire juste étape par étape ce qu'il y a lieu de faire ?

    1) On me donne un fichier famille.txt (voir plus bas), qui contient pour chacun des membres d'une famille, le nom du père et de la mère s'ils sont connus, 'inconnu' autrement. Ecrire un programme avec une variable famille capable de stocker les informations d'au maximum 10 personnes, et copier les données du fichier dans cette variable et si possible, les afficher.
    Si c'est une variable « famille » qui doit être capable de stocker d'emblée dix individus et que c'est un maximum, c'est que tu n'as pas besoin de recourir à l'allocation dynamique et aux listes chaînées, ce qui est une bonne chose car cela simplifie considérablement le problème.

    Une fois ta structure déclarée, elle est considérée comme un nom de type au même titre que char, int ou float, car on connaît sa taille, qui est toujours la même. De là, le plus simple consiste à déclarer un tableau, comme pour tes entiers ou autres :

    Cette ligne déclare un tableau nommé « famille » qui contient dix éléments de type PersonT, donc tes structures.

    2) Initialiser tous les champs de la structure. Si le père ou la mère sont inconnus, les champs pere et mere doivent être initialisé à NULL. Uiliser la fonction strcmp(chaine1, chaine2).
    Pour cela, il faut faire une boucle qui lit ton fichier et qui garde trace du nombre d'individus déjà enregistrés jusque là, dans un entier. Par exemple : int count;. Comme, au départ, cette variable est nulle (aucun individu enregistré), tu peux directement utiliser cette valeur comme index dans ton tableau « famille » : famille[0] représente le premier individu, famille[1] le second, etc.

    Tu initialises chaque champ, l'un après l'autre, en fonction de ce que tu lis dans ton fichier. Pour remplir les champs « texte » comme « nom » ou « prenom », tu peux utiliser directement fgets() pour déposer le contenu du fichier dans le champ.

    Pour les valeurs numériques, soit tu utilises fscanf pour les remplir directement, mais ce n'est pas ce qu'il y a de plus facile à utiliser, soit tu déclares un buffer quelque part, tu y lis la ligne en cours, et tu décodes l'entier qu'elle contient avec strtol().

    Établir les relations de parenté, par contre, est plus difficile : si tu considères que les parents sont systématiquement cités, dans le fichier, avant leur enfants, alors au moment où tu initialises un individu dans la boucle, il faut passer en revue tous les individus que tu as enregistrés jusque là. Il te faut donc quatre buffers au sein de ta boucle pour lire les noms et prénoms des deux parents de l'individu en cours de traitement. Ensuite, tu écris donc une seconde boucle imbriquée dans la première et qui court de « 0 » à « count-1 » et qui compare ces buffers avec les noms et prénoms de chacun des individus enregistrés. Dès que tu en trouves un (père ou mère), tu mets à jour le pointeur correspondant de l'individu courant. L'arithmétique des pointeurs te permet d'écrire directement « famille + n » si n est l'indice de ta sous-boucle. Tu laisses ensuite continuer la boucle jusqu'à son terme parce qu'il faut également trouver l'autre parent.

    Si, en revanche, les parents peuvent être cités après leur enfants dans le fichier, c'est plus compliqué. Il faudra soit faire une deuxième passe sur le fichier, soit gérer en temps réel une liste chaînée des individus « orphelins » dans laquelle chaque maillon serait une structure qui contiendrait un pointeur vers le membre à compléter et les quatre champs pour les noms et prénoms des parents, ce qui serait un problème encore plus compliqué que celui que tu cherches présentement à mener à bien.

    3)Trier les membres de la famille par ordre alphabétique.
    Pour cela, le plus simple est d'utiliser qsort(), sauf si on t'a explicitement demandé d'implémenter toi-même l'algorithme de tri.

    La fonction qsort() peut trier un tableau d'éléments de n'importe quel type pourvu qu'elle soit capable de les comparer entre eux. Et pour cela, elle fait appel à une fonction qu'on lui passe en argument et qui lui dit si un élément donné est inférieur à un autre.

    Donc, tu écris une fonction « inferieur() » qui reçoit en arguments deux pointeurs de type « PersonT * » et qui en retour renvoie un booléen (un int à 0 ou à 1) indiquant si, oui ou non, la personne pointée par le premier pointeur est « inférieure » à la seconde. Pour ce faire, tu compares les champs un à un en commençant par le premier, et tu ne passes au suivant que si ces deux champs sont égaux, sinon tu renvoies le résultat.

    Dans cette fonction, pour comparer des entiers, tu utilises directement « < ». Pour comparer des chaînes, tu utilises la fonction « strcmp » que l'on t'a indiquée.

    Tu appelles ensuite qsort() une seule fois en passant dans l'ordre le nom de ton tableau, la taille d'un élément, le nombre d'éléments qu'il contient et le nom de ta fonction « inferieur ». Ton tableau sera automatiquement trié.

    4) Plutôt que de matérialiser les relations pere/mere, on souhaite matérialiser la relation enfants, en ajoutant dans chaque structure un tableau de pointeur vers des personnes, de la façon suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct person
    {
    	char nom[32];
    	char prenom[32];
    	int jour, mois, annee, index;
    	struct person *enfants[4];
    } PersonT;
    Écrire un programme qui lit le fichier famille.txt, et initialise tous ses champs de façon à
    pouvoir retrouver directement tous les enfants de chaque personne.
    C'est le même problème mais à l'envers : tes enfants viennent toujours après les parents donc, au départ, le tableau « enfant » de chaque individu sera toujours vide. C'est ensuite, au moment de traiter les enfants, qu'il faudra remonter le tableau pour y retrouver les parents. Seule la dernière étape change : lorsque tu as la main à la fois sur un enfant et sur l'un de ses parents, plutôt que stocker un pointeur vers le parents dans l'un des champs « père » ou « mère » de l'enfant, tu stockes un pointeur vers l'enfant dans le tableau « enfants » du parent.

    Difficulté supplémentaire, il faut que tu vérifies au préalable si la première entrée du tableau « enfants » est bien vide et, si elle ne l'est pas, que tu passes à la suivante et que tu refasses le test.

    Et bien sûr, la sous-boucle dont on parlait doit toujours courir jusqu'à son terme puisqu'il faut toujours mettre à jour les deux parents.

  3. #3
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #define MAXSIZE 10
     
    typedef struct person
    {
        char name[32];
        char prenom[32];
        int jour, mois, annee, index;
        struct person *pere, *mere;
    }PersonT;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    int main(int argc, char *argv[])
    {
        PersonT famille[MAXSIZE];//Crée la variable
        PersonT temporaire;
        FILE *fichier;//Le fichier famille.txt
        int i, j;
     
        if((fichier = fopen("famille.txt", "r")) == NULL){
            printf("Impossible d'ouvrir le fichier en lecture !");
            exit(0);
        }
     
        //Le premier cas:
        while(!feof(fichier)){
            if(fgets((char*)famille, MAXSIZE, fichier))//Copie des données dans la variable
                printf("%s", (char*)famille);
        }
        fclose(fichier);
        /*Je ne comprends pas le deuxième cas, j'ai besoin de lire encore et encore sauf si cela
        ressemble à quelque chose comme ca !
        while(!feof(fichier))
        {
            for(count = 0; count = MAXSIZE; count++)
            {
                fgets(famille[count].name, MAXSIZE, fichier);
                fscanf(fichier, "%d")
            }
        }
        */
     
        //Le troisième cas
        /*J'essai de trier par ordre alphabétique, normalement ca devrait
        donner sauf que je n'arrive pas à afficher pour vérifier*/
        for(i = 0; i < MAXSIZE; ++i){
            for(j = i + 1; j < MAXSIZE-1; j++){
                if(famille[i].name < famille[j].name ||
                   (famille[i].name == famille[j].name &&
                   famille[i].prenom < famille[j].prenom)){
                       temporaire = famille[i];
                       famille[i] = famille[j];
                       famille[j] = temporaire;
                   }
            }
        }
        printf("\n");
        return 0;
    }

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 502
    Par défaut
    Quelques remarques en vrac :

    feof() ne fait pas ce que tu crois : http://c.developpez.com/faq/?page=es_general#ES_feof

    fgets() signifie « File : Get String ». C'est une fonction qui sert à lire une chaîne de caractères depuis un flux (par exemple un fichier) et la déposer dans un buffer. Tu ne peux pas t'en servir pour aller directement remplir ta structure en entier, et encore moins un tableau de ces structures.

    Si tu n'arrives pas à tout écrire en une seule fois dans la boucle, tu peux la décomposer, ce que reste une bonne chose : écris une fonction « PersonT ChargerIndividu (FILE *f) » qui prend en entrée un descripteur de fichier et qui te renvoie un individu en sortie. Dans cette fonction, tu déclares une variable de type « PersonT » dont tu vas t'attacher à remplir les champs un à un. Tu utiliseras donc fgets() pour lire le nom de la personne, une seconde fois pour lire son prénom. Tu utilises ensuite soit scanf(), soit fgets() et strtol() pour lire tes nombres. Lorsque tu as fini, tu fais un « return » de la variable en question.

    Ensuite, dans le corps principal de ton programme, tu remplis un à un ton tableau avec une ligne du style « famille[n] = ChargerIndividu(fichier); » en remplaçant n et fichier par ce que tu utilises dans ton programme, bien sûr.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 853
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par honolyani Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        //Le premier cas:
        while(!feof(fichier)){
            if(fgets((char*)famille, MAXSIZE, fichier))//Copie des données dans la variable
                printf("%s", (char*)famille);
        }
        fclose(fichier);
    Salut
    La fonction feof() n'a pas pour but de détecter la fin de fichier mais de t'indiquer, quand une lecture échoue, si l'échec de lecture est dû à une fin de fichier atteinte ou pour une autre raison. Au premier abord on peut croire que ça le fait mais si tu réfléchis bien, ça ne le fait pas.
    Imagine par exemple que tu as 3 éléments dans ton fichier "toto", "titi", "tata"
    1. tu lis la première ligne "toto". La lecture se passe bien donc feof() renvoie faux.
    2. tu lis la seconde ligne "titi". La lecture se passe bien donc feof() renvoie toujours faux.
    3. tu lis la troisième ligne "tata". La lecture se passe encore bien donc feof() renvoie encore faux.
    4. tu fais donc un appel supplémentaire à fgets() (qui ne lit plus rien) puis tu effectues le traitement de la boucle alors que t'as pas d'info
    5. là feof() renvoie vrai donc tu sors

    Total: tu as fait une lecture et un traitement (forcément erroné) pour rien. Ce qui t'oblige à rajouter ce if pour vérifier le fgets()...
    La bonne méthode est de boucler tant que la lecture se fait. Une fois que la boucle est finie, là tu peux, si tu en as envie, vérifier feof() pour savoir si tu es sorti de la boucle à cause de la fin de fichier ou bien pour une autre raison
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (fgets(...))
    {
        // traitement
    }
    if feof(fichier)
    {
        ...
    }
    De plus on ne peut pas benner un flot d'octets dans une structure en vrac en espérant qu'ils iront tous à la bonne place. Déjà il faut savoir que parfois le compilo rajoute des octets de calage entre les champs pour aligner la taille de la structure sur un mot machine (cela lui permet ensuite d'accéder plus vite aux éléments dans le cas d'un tableau). Mais même sans ce détail ça ne peut pas marcher car avec un nom à 32 car et un prénom à 32 car ça implique que ton fichier doit avoir vraiment 32 caractères pour le nom puis 32 caractères pour le prénom. Or avec
    Johnson
    Albert
    ben moi j'en compte 8 pour le nom et 7 pour le prénom (je compte bien entendu les sauts de ligne qui terminent chaque ligne). Puis je vois qu'il y a un "7<enter>" et lui (qui est aussi un caractère) je le vois mal aller dans un champ de type int. Idem pour le reste. Surtout quand on sait que fgets() s'arrête à la fin de chaque ligne...

    Donc si ton fichier est bien formaté (ce qui semble être le cas) je te conseillerais de créer carrément une fonction bien à toi. Cette fonction lirait une première ligne (via fgets) et la stockerait dans le membre nom. Puis elle lirait une seconde ligne et la stockerait dans le prénom. Et etc etc etc. Et elle renverrait bien évidemment 0 ou X permettant de savoir qu'elle a bien lu. Ensuite ben te suffirait de faire un while (ma_fonction_de_lecture(...))...

    Attention aussi à ne pas fermer le fichier si tu as besoin de le lire plusieurs fois. Un petit fseek(fichier, 0, SEEK_SET) et tu te retrouves au début...

    Citation Envoyé par honolyani Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        //Le troisième cas
        /*J'essai de trier par ordre alphabétique, normalement ca devrait
        donner sauf que je n'arrive pas à afficher pour vérifier*/
        for(i = 0; i < MAXSIZE; ++i){
            for(j = i + 1; j < MAXSIZE-1; j++){
                if(famille[i].name < famille[j].name ||
                   (famille[i].name == famille[j].name &&
                   famille[i].prenom < famille[j].prenom)){
                       temporaire = famille[i];
                       famille[i] = famille[j];
                       famille[j] = temporaire;
                   }
            }
        }
    Un peu le même principe que tout à l'heure. Bien qu'il soit tentant de considérer famille[x] et famille[y] comme des éléments uniques et simples ce n'en sont pas. Ce sont des éléments complexes composés de plusieurs champs. On ne peut donc pas les copier comme des int.
    Si tu veux copier une structure dans une autre te faut la copier membre à membre. Ou bien passer par memcpy() qui copie une zone mémoire dans une autre octet par octet. Mais pourquoi ne pas passer par qsort() comme te l'a conseillé Obsidian ? Serait-ce la fainéantise de devoir apprendre un outil inconnu et la crainte de perdre du temps ??? Là pour le coup ta carrière de prog prendrait vraiment un parpaing.
    Surtout que ce n'est vraiment ni long ni compliqué. Te suffit de définir une fonction int xxx() recevant deux pointeurs X et Y de type PersonT et renvoyant
    • -1 si X plus petit que Y (à toi de coder le concept "plus petit que")
    • 1 si X plus grand que Y (idem)
    • 0 sinon

    Et appeler qsort(famille, 10, sizeof(PersonT), xxx) et hop, c'est trié. qsort s'est occupé de tout. Grâce au début du tableau et au nombre d'éléments elle sait où commencer et où s'arrêter. Grâce à l'adresse de la fonction xxx() elle peut exécuter cette fonction xxx() elle-même et donc comparer deux éléments [x] et [y] et grâce à la taille de chaque élément elle peut les permuter octet par octet. Plus rapide à programmer que ton ersatz de tri à bulles même pas optimisé. Et (sauf si par super malchance le tableau est déjà trié mais dans le mauvais sens) aussi 100 fois plus rapide à s'exécuter...

    Tu devrais aussi découper tes étapes. Faire le 1, tester. Quand ça marche passer au 2 etc. Et apprendre à découper les tâches et à les dédier à des fonctions appropriées. Ainsi on peut plus facilement tester chaque tâche...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut
    Voici ce que j'ai pu faire pour le moment avec les conseils de Obsidian, pourquoi cela me renvoie pas une erreur alors que vraisemblablement il y en a une ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    typedef struct person
    {
        char name[32];
        char prenom[32];
        int jour, mois, annee, index;
        struct person *pere;
        struct person *mere;
    }PersonT;
    PersonT chargerIndividu(char *nom_fichier)
    {
        FILE *fichier;
        PersonT honolyani;
        fichier = fopen(nom_fichier, "r");
        if(fichier == NULL){
            printf("Impossible d'ouvrir le fichier !\n");
            exit(0);
        }
     
        while(!feof(fichier)){
            fgets(honolyani.name, 32, fichier);
            fgets(honolyani.prenom, 32, fichier);
            fgets(honolyani.pere->name, 32, fichier);
            fgets(honolyani.pere->prenom, 32, fichier);
            fgets(honolyani.mere->name, 32, fichier);
            fgets(honolyani.mere->prenom, 32, fichier);
            fscanf(fichier, "%d", &honolyani.jour);
            fscanf(fichier, "%d", &honolyani.mois);
            fscanf(fichier, "%d", &honolyani.annee);
        }
     
        fclose(fichier);
        return honolyani;
    }
    int main(int argc, char *argv[])
    {
        PersonT toto;
        toto = chargerIndividu("famille.txt");
        return 0;
    }
    Salut Sve@r, pour ton commentaire :
    Donc si ton fichier est bien formaté (ce qui semble être le cas) je te conseillerais de créer carrément une fonction bien à toi. Cette fonction lirait une première ligne (via fgets) et la stockerait dans le membre nom. Puis elle lirait une seconde ligne et la stockerait dans le prénom. Et etc etc etc. Et elle renverrait bien évidemment 0 ou X permettant de savoir qu'elle a bien lu. Ensuite ben te suffirait de faire un while (ma_fonction_de_lecture(...))...

    Attention aussi à ne pas fermer le fichier si tu as besoin de le lire plusieurs fois. Un petit fseek(fichier, 0, SEEK_SET) et tu te retrouves au début...

    Cela suppose que je devrais compter les champs de la structure et attribuer à chaque champ, une valeur etc, etc ?

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 502
    Par défaut
    Citation Envoyé par honolyani Voir le message
    Voici ce que j'ai pu faire pour le moment avec les conseils de Obsidian, pourquoi cela me renvoie pas une erreur alors que vraisemblablement il y en a une ?
    Tout d'abord, je te conseillais de passer le descripteur de fichier (ouvert) à ta fonction pour qu'elle l'exploite, et pas de lui passer le nom de fichier pour qu'elle l'ouvre elle-même, sinon tu vas te retrouver à faire des ouvertures/fermetures incessantes et, à chaque fois, tu vas te retrouver au début de ton fichier.

    Ensuite, tu fais tes lectures dans le désordre : tes fgets() et fscanf() ne correspondent pas à l'ordre dans lequel sont enregistrées les différentes informations dans ton fichier.

    Enfin, et surtout, tu ne peux pas faire directement ceci :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            fgets(honolyani.pere->name, 32, fichier);
            fgets(honolyani.pere->prenom, 32, fichier);
            fgets(honolyani.mere->name, 32, fichier);
            fgets(honolyani.mere->prenom, 32, fichier);

    … ne serait-ce que parce que, justement, tu ne sais pas encore qui sont tes père et mère. Il faut stocker les noms et prénoms que tu lis de ton fichier dans des buffers distincts puis que tu compares le contenu de ces buffers aux champs « nom » et « prenom » de chacune des entrées de ton tableau. Lorsque l'une d'entre elles correspond, tu récupères son adresse et tu la stockes dans « honolyani.pere » ou « honolyani.mere ».

    À noter enfin que lorsque tu déclares une variable de type PersonT ou n'importe quoi d'autre, tu ne fais que réserver son espace en mémoire qui reste donc tel qu'il est au départ. Il est donc important d'initialiser tes champs, en mettant les pointeurs à NULL par exemple.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 853
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par honolyani Voir le message
    Salut Sve@r, pour ton commentaire :
    Donc si ton fichier est bien formaté (ce qui semble être le cas) je te conseillerais de créer carrément une fonction bien à toi. Cette fonction lirait une première ligne (via fgets) et la stockerait dans le membre nom. Puis elle lirait une seconde ligne et la stockerait dans le prénom. Et etc etc etc. Et elle renverrait bien évidemment 0 ou X permettant de savoir qu'elle a bien lu. Ensuite ben te suffirait de faire un while (ma_fonction_de_lecture(...))...

    Cela suppose que je devrais compter les champs de la structure et attribuer à chaque champ, une valeur etc, etc ?
    C'est l'idée. Puisque ta structure contient un nom, un prénom et un âge et que ton fichier contient un nom, un prénom et un âge, ça peut se faire. Tu fais fgets() => ça te donne la première ligne que tu stockes dans le nom. Puis tu fais un nouvel fgets() ce qui te donne la ligne suivante que tu stockes dans le prénom. Puis tu fais un nouvel fgets() qui te donne la ligne suivant que tu stockes dans l'âge. Puis... jusqu'à ce que tu aies stocké un élément complet. Là ta fonction se termine et renvoie "1". Ensuite tu la rappelles pour l'élément suivant...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Cherche cours et exercices sur les arbres binaires
    Par dzsystem dans le forum Pascal
    Réponses: 3
    Dernier message: 01/03/2009, 22h34
  2. Cours sur les arbres binaires
    Par Fredo123456 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 09/10/2008, 16h45
  3. Questions diverses sur les Arbres binaires + insertion d'un fils
    Par beegees dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 18/03/2008, 01h21
  4. Demande sur les arbres binaire
    Par IDE dans le forum C++
    Réponses: 12
    Dernier message: 02/12/2007, 17h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo