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 :

Problème avec les listes chainées


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 6
    Par défaut Problème avec les listes chainées
    Bonjour

    Pour un exercice sur les liste chainées, je dois insérer un élément en tête de liste et l'afficher ensuite.
    Mais lors de l'exécution, ça plante et je ne vois pas pourquoi.
    Pourriez-vous m'orrienter dans ma recherche de l'erreur (je pense que c'est dans ma fonction d'affichage mais il y a surement d'autres problèmes )
    Si vous avez des suggestions pour améliorer mon code n'hésitez pas non plus
    Je vous remercie d'avance

    Voici mon code :

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define TAILLE 200
     
     
     
    struct i
    {
        char nom[TAILLE];
        char prenom[TAILLE];
        char ville[TAILLE];
        int age;
        struct i *psuiv;
    };
     
    void saisie(struct i *pointeur);
    void affichage(struct i *pointeur);
    void creeElement(char *nom,char *prenom,char *ville,int age,struct i *pointeur);
    void insereTeteListe(struct i *premier,struct i *pointeur);
    void afficherListe(struct i *liste);
     
    int main()
    {
        struct i info,info2,info3,ptete;
        printf("Hello world!\n");
        //saisie(&info);
        creeElement("Thomas","Jean","Paris", 20,&info);
        affichage(&info);
     
        creeElement("Messier","Maxime","Lyon", 19,&info2);
        affichage(&info2);
     
        creeElement("Perry","Fred","Londres", 70,&info3);
        affichage(&info3);
     
        ptete = info;
        info.psuiv = &info2;
        info2.psuiv = NULL;
        /*info2.psuiv = &info3;
        info3.psuiv = NULL;*/
     
        //afficherListe(&ptete);
        insereTeteListe(&ptete,&info3);
        afficherListe(&ptete);
     
        return 0;
    }
     
    void saisie(struct i *pointeur)
    {
        printf("Saisissez votre nom : \n");
        gets(pointeur->nom);
        printf("Saisissez votre prenom : \n");
        gets(pointeur->prenom);
        printf("Saisissez votre ville : \n");
        gets(pointeur->ville);
        printf("Saisissez votre age : \n");
        scanf("%d",&pointeur->age);
    }
     
    void affichage(struct i *pointeur)
    {
        printf("Vous vous appelez : %s %s \n",pointeur->prenom,pointeur->nom);
        printf("Vous etes de : %s \n",pointeur->ville);
        printf("Vous avez : %d ans\n",pointeur->age);
    }
     
    void afficherListe(struct i *liste)
    {
        struct i *tmp = liste;
        /* Tant que l'on n'est pas au bout de la liste */
        while(tmp != NULL)
        {
            /* On affiche */
            printf("%s %s %s %d \n", liste->prenom,liste->nom,liste->ville,liste->age);
            /* On avance d'une case */
            tmp = tmp->psuiv;
        }
     
    }
     
    void creeElement(char *nom,char *prenom,char *ville,int age,struct i *pointeur)
    {
        strcpy(pointeur->nom ,nom);
        strcpy(pointeur->prenom ,prenom);
        strcpy(pointeur->ville ,ville);
        pointeur->age = age;
    }
     
    void insereTeteListe(struct i *premier,struct i *pointeur)
    {
        struct i *temp;
     
        temp = premier;
        premier = pointeur;
        pointeur = temp;
     
    }
    P.S : Ce qui est en commentaire dans le main fait partie de mes tests ou d'un exercice précédent

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    C'est dans ta fonction d'affichage que le plantage a lieu mais la cause du plantage n'est pas la fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ptete = info;
    info.psuiv = &info2;
    info2.psuiv = NULL;
    Tu copies info dans ptete et ensuite tu renseignes psuiv. ptete ne devrait-il pas plutôt est un pointeur sur structure struct i et pointé vers info ? Ainsi, lorsque info est modifié, ptete "suit" le changement.

    Autre solution : mettre la 1ere ligne après la 2nde.

    En revanche, dans ton fonction d'affichage de liste, tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%s %s %s %d \n", liste->prenom,liste->nom,liste->ville,liste->age);
    alors que tu devrais utiliser tmp.

    De plus, ta fonction InsererTete me parait très douteuse.

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Ton code est mal fichu :

    - void saisie(struct i *pointeur).
    Ne pas utiliser gets(), mais fgets() sur le flux stdin

    - void afficherListe(struct i *liste).
    Erreur dans l'affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%s %s %s %d \n", tmp->prenom,tmp->nom,tmp->ville,tmp->age);
    - void creeElement(char *nom,char *prenom,char *ville,int age,struct i *pointeur).
    Nom trompeur : ne crée pas un élément, mais initialise un élément existant.
    Une fonction de création devrait être, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct i * creeElement(char *nom,char *prenom,char *ville,int age)
    {
       // création d'un élément : malloc()
       // test de la réussite de malloc()
       // initialisation de l'élément créé (comme avant avec en plus l'initialisation de psuiv à NULL)
       // retour de l'adresse de l'élément créé
    }
    -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void insereTeteListe(struct i *premier,struct i *pointeur)
    {
        struct i *temp;
     
        temp = premier;
        premier = pointeur;
        pointeur = temp;
     
    }
    Ne marche pas: ne fait que modifier les variables locales premier et pointeur.
    La fonction doit pouvoir modifier la tête de la liste, donc l'argument doit être l'adresse de la tête de la liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void insereTeteListe(struct i **adTete,struct i *pointeur)
    {
      //- Mettre pointeur->psuiv sur le premier élément de la liste (*adTete)
      //- Mettre pointeur en premier élément de la liste 
      //  on peut vérifier que cela marche même si la liste était vide (*adTete == NULL) 
    }
    main() prend comme allure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main(void)
    {
      struct i * Tete = NULL;
      struct i * p;
      p = creeElement("Thomas","Jean","Paris", 20);
      if(p!=NULL) insereTeteListe(&Tete, p);
      p = creeElement("Messier","Maxime","Lyon", 19);
      if(p!=NULL) insereTeteListe(&Tete, p);
      affichage(Tete);
      return 0;
    }

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 6
    Par défaut
    D'abord, merci pour vos réponses

    Vous avez raison pour le remplacement dans ma fonction d'affichage de liste par tmp (petite erreur de ma part ^^)

    Par contre diogene, j'ai essayé de reprendre mon code avec ce que tu m'as dis mais cela ne marche toujours pas
    Je pense que cela vient du fait que je n'ai pas très bien compris comment tu comptais faire l'insertion en tête de liste donc pourrais-tu me l'expliquer s'il te plait ? (désolé je débute sur les structures et les listes chaînées et j'ai du mal à voir comment cela fonctionne )

    Voici mes fonctions :

    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
    void affichage(struct i *pointeur)
    {
        printf("Vous vous appelez : %s %s \n",pointeur->prenom,pointeur->nom);
        printf("Vous etes de : %s \n",pointeur->ville);
        printf("Vous avez : %d ans\n",pointeur->age);
    }
     
    void afficherListe(struct i *liste)
    {
        struct i *tmp = liste;
        /* Tant que l'on n'est pas au bout de la liste */
        while(tmp != NULL)
        {
            /* On affiche */
            printf("%s %s %s %d \n", tmp->prenom,tmp->nom,tmp->ville,tmp->age);
            //affichage(tmp);
            /* On avance d'une case */
            tmp = tmp->psuiv;
        }
    }
     
    struct i * creeElement(char *nom,char *prenom,char *ville,int age)
    {
        // création d'un élément : malloc()
        struct i *new_element = malloc(sizeof(struct i));
        // test de la réussite de malloc()
        if(!new_element) exit(EXIT_FAILURE);
        // initialisation de l'élément créé (comme avant avec en plus l'initialisation de psuiv à NULL)
        new_element->nom;
        new_element->prenom;
        new_element->ville;
        new_element->age;
        new_element->psuiv = NULL;
        // retour de l'adresse de l'élément créé
        return new_element;
    }
     
    void insereTeteListe(struct i **adTete,struct i *pointeur)
    {
        //- Mettre pointeur->psuiv sur le premier élément de la liste (*adTete)
        pointeur->psuiv = *adTete;
        //- Mettre pointeur en premier élément de la liste
        *adTete = pointeur;
        //  on peut vérifier que cela marche même si la liste était vide (*adTete == NULL)
    }

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il faut être un peu attentif à ce qu'on fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct i * creeElement(char *nom,char *prenom,char *ville,int age)
    {
    ...    // initialisation de l'élément créé (comme avant avec en plus l'initialisation de psuiv à NULL)
        new_element->nom;
        new_element->prenom;
        new_element->ville;
        new_element->age;
        new_element->psuiv = NULL;
        // retour de l'adresse de l'élément créé
        return new_element;
    }
    Il est évident que les lignes en rouge ne font rien et sont radicalement différentes du code que tu avais utilisé précédemment

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 6
    Par défaut
    Ok merci beaucoup
    J'ai fais le test et sa marche

    Par contre, juste deux petites questions :
    - tu m'as parlé de la fonction fgets mais je ne la connais pas, quelle est la différence avec gets ?

    - en fait ta fonction "insereTeteListe" te sert à "lier" ta liste chaînée si j'ai bien compris ? et tu fais une inversion des adresses des deux éléments c'est ça ?

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par t-mac06 Voir le message
    - tu m'as parlé de la fonction fgets mais je ne la connais pas, quelle est la différence avec gets ?
    Tu ne connais pas les pages magiques : http://man.developpez.com/ ?

    Pour la différence entre gets et fgets, visite http://man.developpez.com/man3/gets.3.php.

    gets récupère des caractères depuis l'entrée standard jusqu'à l'obtention d'un caractère de fin de ligne ou du caractère EOF. Potentiellement, elle pourrait récupérer une infinité de caractères. Cette fonction est à bannir : il est très facile de récupérer plus de caractères que ne peut en contenir la zone réceptrice ("oh ! j'ai fait char tab[10] et l'utilisateur a tapé 20 caractères !").

    fgets récupère au plus N caractères (N-1 lus + '\0') depuis le flux précisé. Tu peux donc accorder les tailles entre la lecture et la zone réceptrice.

    Tout est expliqué dans la page de manuel

  8. #8
    Membre très actif
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Par défaut Mon dieu, les listes chainées en C++
    Bonjour,
    ça fait longtemps que je n'ai pas ecrit une seule ligne de code en C++, j'ai peur
    Cordialement

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 6
    Par défaut
    Et non je ne connaissais pas les pages magiques je viens tout juste de m'inscrire

    Merci pour les informations je comprends mieux maintenant la différence

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par buggen25 Voir le message
    ça fait longtemps que je n'ai pas ecrit une seule ligne de code en C++, j'ai peur
    Heureusement qu'on fait du C alors, tu as moins peur dans ce cas



    Citation Envoyé par t-mac06 Voir le message
    Et non je ne connaissais pas les pages magiques je viens tout juste de m'inscrire
    Les pages de manuel ne sont pas une exclusivité de Developpez.com. Tape "man page" dans Google et tu verras. A savoir que "pages de manuel" sous-entend souvent "pages de manuel Linux" mais l'information est souvent transférable à Windows pour les fonctions standards. A titre d'(e contre-)exemple, tu trouveras sleep() mais pas Sleep() dans http://man.developpez.com

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 6
    Par défaut
    Ok je vois je débute donc je ne connais pas tout

  12. #12
    Membre très actif
    Avatar de buggen25
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    554
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Août 2008
    Messages : 554
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Heureusement qu'on fait du C alors, tu as moins peur dans ce cas
    Mais tu plaisantes, ya meme pas de classes, faut faire gaffe a la calvecie enfin pour ceux qui vont faire du php au future, c'est un bon début

  13. #13
    Invité de passage
    Femme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2012
    Messages : 1
    Par défaut merci d avance
    Bonjour,

    est ce qu'il y'a qlq peut m'aider à ce programme en langage C

    écrire un programme en C qui saisie une chaine de caractère alphabétique " maman est là " dans une pile chaque mots dans une case de la pile


    mille merci d avance

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec les listes chainées
    Par Naswd_94 dans le forum Débuter
    Réponses: 8
    Dernier message: 09/03/2015, 10h40
  2. un problème avec les listes chainées
    Par chmek firas dans le forum Débuter
    Réponses: 4
    Dernier message: 05/05/2012, 06h55
  3. petit problème avec les listes chainées
    Par djinpark1 dans le forum Débuter
    Réponses: 4
    Dernier message: 30/06/2009, 17h11
  4. Problème avec les listes chainées
    Par reeda dans le forum C++
    Réponses: 10
    Dernier message: 23/04/2008, 16h21

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