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 :

Listes simplement chainees - problème de pointeurs


Sujet :

C

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut Listes simplement chainees - problème de pointeurs
    Bonjour,

    Je débute en C et j'ai du mal avec les pointeurs enclus dans les "Typedef struct".

    On doit réaliser un programme qui va gérer une collection de BD.

    Les typesdef struct suivants nous sont donnés:

    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
    typedef struct _un_element_series *P_un_element_series;
     
     
    typedef struct _un_element_series {
      char mot[30];
      struct Serie_s * element;
      P_un_element_series suivant;
    } Un_element_series;
     
    typedef struct _un_element_tomes *P_un_element_tomes;
     
     
    typedef struct _un_element_tomes {
      char mot[30];
      struct Tome_s * element;
      P_un_element_tomes suivant;
    } Un_element_tomes;
     
    typedef struct _un_element_auteurs *P_un_element_auteurs;
     
    typedef struct _un_element_auteurs {
      char mot[30];
      char * nom;
      P_un_element_auteurs suivant;
    } Un_element_auteurs;
     
    typedef struct Serie_s {
      char *titre;
      char *pays_parution;
      int nb_parus;
      P_un_element_tomes tomes;
    } Une_serie;
     
    typedef struct Tome_s {
      char *titre;
      P_un_element_auteurs scenaristes;
      P_un_element_auteurs dessinateurs;
      int no_serie;
    } Un_tome;

    Il est d'abord demandé d'écrire deux fonctions qui creent une serie et un tome, ce que j'ai fait:

    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
    Une_serie *creer_serie(char *nom_serie, char *pays_parution, int nb_parus) {
    Une_serie *serie = (Une_serie *)malloc(sizeof(Une_serie));
        serie->titre=strdup(nom_serie);
        //serie->pays_parution=strdup(pays_parution);
        strcpy(serie->pays_parution, pays_parution);
        serie->nb_parus=nb_parus;
    	return serie;
    }
     
     
    Un_tome *creer_tome(char *titre, P_un_element_auteurs scenaristes, 
    P_un_element_auteurs dessinateurs, int no_serie) {
       Un_tome *tome = (Un_tome *)malloc(sizeof(Un_tome));
        tome->titre=strdup(titre);
        tome->scenaristes=scenaristes;
        tome->dessinateurs=dessinateurs;
        tome->no_serie=no_serie;
    	return tome;
    }

    Est-ce correct?

    Mon probleme est au niveau de la fonction ajouter_serie_a_collection:

    code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void ajouter_serie_a_collection(P_un_element_series *collectionSeries, P_un_element_series *serie) {
    assert(collectionSeries);
    assert(serie);
    Une_serie *serie_test=NULL;
    serie_test=chercher_serie(collectionSeries,serie->element->titre);
    //if(serie_test) return NULL;
    //inserer_element_fin_series(collectionSeries,serie);
    }


    J'essais de récupérer la valeur du titre (serie->element->titre) contenue dans le struct serie avec appel via la liste serie ramenée en 2eme argument de ajouter_serie_a_collection. La fonction chercher_serie necessite un char en deuxieme argument ainsi le titre de la serie. J'obtiens cette erreur : "request for member ‘element’ in something not a structure or union". Il y a tellement de pointeurs que je suis perdue et je ne sais pas comment retrouver la valeur titre.

    J'ai egalement essayer *(serie.element)->titre et &(*(serie.element)->titre) mais rien ne marche.

    Pouvez-vous m'aider?

    Merci par avance

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    J'en ai vu des codes dégueulasses écrits par les équipes pédagogiques mais alors celui-ci c'est limite du trolling.

    Tu es larguée parce que ce qu'on t'as donné est imbitable et ni fait, ni à faire. Quoiqu'il en soit va falloir que tu te débrouilles avec alors voici quelques pistes en vrac :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct _un_element_series *P_un_element_series; // ici on déclare 'P_un_element_series' comme alias d'un pointeur de type 'struct _un_element_series'
     
    P_un_element_series ptr1; // ptr1 est donc de type 'struct _un_element_series *'
     
    P_un_element_series *ptr2 = &ptr1; // ptr2 est de type 'struct _un_element_series **' (pointeur de pointeur de ...) et est initialisé à l'adresse de ptr1
     
    *ptr1 = **ptr2; // la 'struct _un_element_series' pointée par ptr1 est initialisée à celle pointée par le pointeur pointé par ptr2 (capice ? ^^)
    Calmes-toi, comptes les astérisques et souviens-toi de celles dissimulées par les typedef du prof. Ajoutes un commentaire pour chaque variable et paramètre s'il le faut.

    serie_test=chercher_serie(collectionSeries,serie->element->titre); : ici le compilateur ne trouve pas element car serie n'est pas un P_un_element_series, c'est un P_un_element_series *. Modifies la signature de ta fonction, tu n'as sans doute pas besoin du niveau d'indirection supplémentaire.


    Une petite erreur que j'ai notée en passant : pourquoi as-tu commenté le second strdup de la première fonction ? Tu ne peux pas faire un strcpy vers un buffer non alloué ça va péter. Utilises malloc avant ou fais comme pour le champ titre, c'était bien.

  3. #3
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Ok merci Matt,

    Je me suis debarrassée du pointeur sur l'element serie et ça marche.

    Citation Envoyé par Matt_Houston Voir le message

    Une petite erreur que j'ai notée en passant : pourquoi as-tu commenté le second strdup de la première fonction ? Tu ne peux pas faire un strcpy vers un buffer non alloué ça va péter. Utilises malloc avant ou fais comme pour le champ titre, c'était bien.
    Et oui, la version correcte de la fonction creer serie est bien:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Une_serie *creer_serie(char *nom_serie, char *pays_parution, int nb_parus) {
    Une_serie *serie = (Une_serie *)malloc(sizeof(Une_serie));
        serie->titre=strdup(nom_serie);
        serie->pays_parution=strdup(pays_parution);
        strcpy(serie->pays_parution, pays_parution);
        serie->nb_parus=nb_parus;
    	return serie;
    }
    Merci encore pour ton aide!

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    N'oublies pas de vérifier les valeurs de retour des fonctions de bibliothèque ! malloc peut échouer, strdup aussi et pour les mêmes raisons.

  5. #5
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Bonjour Matt,

    Peux tu me guider comment faire cette verification? je peux maintenant compiler mais quand j'essais de lancer le programme j'obtiens au bus error au niveau de la fonction chercher serie. Cela pourrait-il venir du malloc?

    Merci par avance

  6. #6
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Pour commencer un simple assert fera l'affaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <assert.h>
     
    // ...
     
    foo *ptr = malloc(sizeof(foo));
    assert(ptr != NULL); // si ptr != NULL n'est pas vérifié, l'exécution du programme est immédiatement interrompue
    Dans ton cas je pencherais pour une erreur de programmation qui a entraîné une corruption de mémoire ou un truc du même style. Peux-tu nous donner plus d'information sur l'erreur (comportement du programme en détail, sortie exacte sur le terminal...) ? Est-ce que ton code compile sans warnings ? Si tu utilises GCC, ajoutes -Wall -Wextra aux options de compilation.

  7. #7
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Pour commencer un simple assert fera l'affaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <assert.h>
     
    // ...
     
    foo *ptr = malloc(sizeof(foo));
    assert(ptr != NULL); // si ptr != NULL n'est pas vérifié, l'exécution du programme est immédiatement interrompue
    J'ai rajouté cette option à mon programme. L'erreur n'a pas l'air de venir des mallocs.

    Citation Envoyé par Matt_Houston Voir le message
    Dans ton cas je pencherais pour une erreur de programmation qui a entraîné une corruption de mémoire ou un truc du même style. Peux-tu nous donner plus d'information sur l'erreur (comportement du programme en détail, sortie exacte sur le terminal...) ? Est-ce que ton code compile sans warnings ? Si tu utilises GCC, ajoutes -Wall -Wextra aux options de compilation.
    Le programme compile normalement et sans warnings. J'utilise gcc -Wall -g -o test test.c. La commande -Westra n'est en revanche pas reconnue par ma version de gcc. Quand je rentre dans le debuggage en step, il s'agirait effectivement d'une erreur d'accés à la mémoire. Le compilateur me renvoit ce message à l'entrée dans la fonction chercher serie.

    "Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
    0x00002a4d in main () at test.c:489
    "
    J'obtiens la meme erreur a l'entre de chercher_tome. (ligne 94 du code ajouté en dessous)

    La ligne 489 corresponds a l'entree Une_serie *serie=chercher_serie(*collectionSeries, titre); de la fonction main (ligne 84 dans le code en dessous)

    J'ajoute le code entier avec le main ici:

    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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
     
    #include "structuretest.h" 
    // sont contenus dans structuretest.h les signatures de l'ensemble des fonctions du programme présenté ici ainsi que les typede f struct donnés dans mon précédent message
     
    Une_serie *creer_serie(char *nom_serie, char *pays_parution, int nb_parus) {
    Une_serie *serie = (Une_serie *)malloc(sizeof(Une_serie));
    assert(serie != NULL);
        serie->titre=strdup(nom_serie);
        serie->pays_parution=strdup(pays_parution);
        strcpy(serie->pays_parution, pays_parution);
        serie->nb_parus=nb_parus;
    	return serie;
    }
     
    Un_tome *creer_tome(char *titre, P_un_element_auteurs scenaristes, 
    P_un_element_auteurs dessinateurs, int no_serie) {
       Un_tome *tome = (Un_tome *)malloc(sizeof(Un_tome));
       assert(tome!= NULL);
        tome->titre=strdup(titre);
        tome->scenaristes=scenaristes;
        tome->dessinateurs=dessinateurs;
        tome->no_serie=no_serie;
    	return tome;
    }
     
     
    // //trim function -> 
    void trim(char *str) {
      int pos = strlen(str) - 1;
      while (pos > 0) {
        char ch = str[pos];
        if ((ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r')) {
          str[pos] = 0;
        } else {
          break;
        }
        pos--;
      }
    }
     
    //chercher serie
    Une_serie *chercher_serie(P_un_element_series collectionSeries,char *titre) {
    //assert(collectionSeries);
    while(collectionSeries){
    if(strcmp(collectionSeries->mot,titre)!=0){
    collectionSeries=collectionSeries->suivant;
    Une_serie *serie=(Une_serie *)malloc(sizeof(Une_serie));
    assert(serie != NULL);
    serie->titre=collectionSeries->mot;
    return serie;
    }
    }
    return NULL;
    }
     
    int main() {
     
    char titre[MAXINPUT + 1];
    int saisie;
     
    P_un_element_series *collectionSeries=NULL;
    //lire_collection(*collectionSeries,"collection.csv");
     
        for(;;){
        /*-----------------------------------------*/
        printf("\n");
        printf("Menu Utilisateur\n");
        printf("1. Rechercher une serie.\n");
        printf("2. Rechercher un tome.\n");
        printf("3. Saisir un nouveau tome.\n");
        printf("4. Saisir une nouvelle serie.\n");
        printf("0. sortir.\n");
        scanf("%d", &saisie);
        fgets(titre, MAXINPUT, stdin); 
     
        switch (saisie) {
        case 1:
         printf("Recherche d'une serie : Donnez le titre d'une serie\n");
         fgets(titre,MAXINPUT,stdin);
         trim(titre);
         Une_serie *serie=chercher_serie(*collectionSeries, titre);
         if(serie){
         afficher_serie(serie);
          }
          break;
          /*-----------------------------------------*/
        case 2:
        printf("Recherche d'un tome:Donnez le titre d'un tome\n");
        fgets(titre, MAXINPUT, stdin);
        trim(titre);
        Un_tome *tome=chercher_tome(*collectionSeries, titre);
        if(tome!=NULL){
        printf("Le tome est present dans la collection, il fait partie \n");
        printf("de la serie: %s\n",tome->titre);
         } else  {
         printf("Le tome n'a pas ete trouve dans la collection!\n");     
         }
          break;
     
        case 3:
          printf("Saisir un nouveau tome: \n");
          saisir_tome(collectionSeries);
          break;
          /*-----------------------------------------*/
        case 4:
         printf("Saisir une nouvelle serie: \n");
          saisir_serie(collectionSeries);
          break;
        case 0:
          exit(1);
          break;
        default: {
          printf("Mauvaise saisie; reessayez!\n");
          }
     }
     }
      return 0;
    }
    Le menu "main" est aussi a creer. On nous a fourni la liste de ce que le main devait faire pour utiliser les fonctions.

    Merci encore - J'espère que j'en ne demande pas trop?

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 190
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 190
    Points : 17 146
    Points
    17 146
    Par défaut
    assert ne fonctionne qu'en débug.
    L'adresse qui pose problème est 0X00000000 c'est à dire 0 = NULL.

    Tu as un *NULL quelque part.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    -Wextra avec un x ?


    Citation Envoyé par Audinet Voir le message
    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
    0x00002a4d in main () at test.c:489
    0x00000000 ça ressemble à un pointeur nul ça. Les valeurs affichées par le débugger semblent ok ?

    Utilises également la macro assert pour valider les préconditions des endroits clefs de ton programme. Par exemple si tu réalises une opération sur une liste et qu'à cet endroit la liste en question n'est pas sensée être vide, ajoutes au-dessus : assert(!is_empty(l)); . Cela permet d'identifier l'origine d'une erreur avant que cette dernière fasse boule de neige.

    Si tu as accès à l'outil valgrind c'est le top pour débugger ce qui est relatif aux accès mémoire en C. Il faut cependant un temps d'apprentissage pour l'utiliser efficacement.


    Citation Envoyé par Audinet Voir le message
    Merci encore - J'espère que j'en ne demande pas trop?
    Déstresses on est sur un forum, personne ne force personne à faire quoi que ce soit.


    Citation Envoyé par leternel Voir le message
    assert ne fonctionne qu'en débug.
    Précisément si NDEBUG n'est pas défini. Je ne suis jamais tombé sur une version de GCC qui le définisse mais ça existe peut-être.

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Déjà, si tu fais des strdup(), inutile de passer des pointeurs non-const:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Une_serie *creer_serie(char const *nom_serie, char const *pays_parution, int nb_parus) {
    	Une_serie *serie;
    	assert(nom_serie != NULL);
    	assert(pays_parution != NULL);
    	serie = malloc(sizeof(Une_serie)); /*Pas besoin de cast en C*/
    	assert(serie != NULL); /*ici il faudrait mieux qu'un assert mais c'est mieux que rien*/
     
    	serie->titre = strdup(nom_serie);
    	serie->pays_parution = strdup(pays_parution);
    	serie->nb_parus=nb_parus;
    	return serie;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    En attente de confirmation mail

    Profil pro
    Inscrit en
    Septembre 2013
    Messages
    639
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 639
    Points : 2 347
    Points
    2 347
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    J'en ai vu des codes dégueulasses écrits par les équipes pédagogiques mais alors celui-ci c'est limite du trolling.
    N'hésite pas à montrer à Audinet comment tu l'aurais écrit. C'est toujours instructif de voir du bon code écrit par un vrai pro.

  12. #12
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Merci Matt et Leternel, il s'agissait bien d'un *NULL.

    Citation Envoyé par Matt_Houston Voir le message

    assert(!is_empty(l));
    Cette commande marche pas pour moi. Le terminal renvois:

    test.c:123: warning: implicit declaration of function ‘IsEmpty’
    Undefined symbols:
    "_IsEmpty", referenced from:
    _chercher_serie in ccaNmcSu.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status

    Pourtant j'ai bien #include <assert.h>. J'ai préalablement essayé is_empty.

    Je n'ai pas valgrind mais ça serait bien que j'installe.

    Merci bien.

    [/QUOTE]

  13. #13
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Bonsoir Médinoc,

    Quelle est la différence entre faire et ne pas faire des casts pour le programme?

    Merci

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Chaque cast de pointeur est une source potentielle d'erreurs.
    Surtout un cast qui retire le "const": cela donne un code qui n'est pas const-correct, où l'on risque de modifier accidentellement des choses qu'on n'est pas censé modifier.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 190
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 190
    Points : 17 146
    Points
    17 146
    Par défaut
    Un cast explicite consiste à dire au compilateur: "Je sais que ce n'est pas le cas, mais fais comme si <truc> était du type <machin>".
    Bien sûr, ca n'est pas le cas, et quand il fait une opération qui dépend la nature du truc en question, ca casse.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  16. #16
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par CodeurPlusPlus Voir le message
    N'hésite pas à montrer à Audinet comment tu l'aurais écrit. C'est toujours instructif de voir du bon code écrit par un vrai pro.
    Haha j'y penserai ouais. Mais bon là présentement j'ai des trucs de vrai pro à terminer. Peace.


    Citation Envoyé par Audinet Voir le message
    Cette commande marche pas pour moi. Le terminal renvois:

    test.c:123: warning: implicit declaration of function ‘IsEmpty’...
    Il s'agissait d'un simple exemple à adapter, rien de concret. Sers-toi d'assert pour t'assurer que les conditions essentielles à la bonne exécution de ton programme sont vérifiées, c'est tout.

  17. #17
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    OK merci à tous

    Citation Envoyé par Matt_Houston Voir le message
    Haha j'y penserai ouais. Mais bon là présentement j'ai des trucs de vrai pro à terminer. Peace.
    Ouais ça serait cool Matt, quand tu as le temps... de voir du code de vrais professionnels

  18. #18
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Je pense que CodeurPlusPlus taquinait, de toute façon professionnellement je n'écris presque pas de C..

    Si ça t'intéresses n'hésites pas à passer un peu de temps sur github à parcourir les projets open-source, c'est un bon exercice. Commences tout petit, pas par FFmpeg quoi.

  19. #19
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Je pense que CodeurPlusPlus taquinait, de toute façon professionnellement je n'écris presque pas de C..

    Si ça t'intéresses n'hésites pas à passer un peu de temps sur github à parcourir les projets open-source, c'est un bon exercice. Commences tout petit, pas par FFmpeg quoi.
    OK merci. C'est vrai que ça l'air compliqué pour moi qui bute sur des choses simples... Toujours dans l'exercice sur les BD, on doit générer une base de données en important les données série (et plus tard ceux des tomes) d'un fichier txt fourni que voici:

    Nom : Picture 1.png
Affichages : 463
Taille : 14,7 Ko

    J'ai donc à écrire une fonction qui va ouvrir le fichier, lire les données et les enregistrer dans la collection des series (collectionSeries):

    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
    void lire_collection(P_un_element_series *collectionSeries, char *nom_fichier) {  
     FILE *f;
     char buff[256];
     char *res;
     Une_serie *serie;
     
     f = fopen(nom_fichier,"r");
     if(f==NULL){
     fprintf(stderr, "Ouverture de %s impossible\n", nom_fichier);
     exit(1);
    }
     
    //lecture de la première ligne
    res=fgets(buff, 256, f);
     
    //tant que la fin du fichier n'est pas atteinte
    while (res!=NULL){
    // detecter une ligne vide
    if (res==NULL){
    break;
    }
     
    serie=creer_serie_depuis_ligne(buff);
    if(serie!=NULL){
    P_un_element_series series_elem=malloc(sizeof(Un_element_series));
    series_elem->element=serie;
    series_elem->suivant=NULL;
    ajouter_serie_a_collection(collectionSeries,series_elem);
    printf("%s\t %s\n", serie->titre, serie->pays_parution);
     
    //lecture de la ligne suivante
    res=fgets(buff, 256, f);
    }
    }
    // fermeture du fichier
    //fclose(f);
     
     
    }
    Prealablement on nous demande d'ecrire une fonction qui va creer la serie depuis la ligne du fichier. Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Une_serie * creer_serie_depuis_ligne(char *ch){
     char **table=decompose_ligne(ch,3);
     if (table==NULL){
     return NULL;
    }
    Une_serie *serie=creer_serie(table[0], table[1], atoi(table[2]));
    free(table[0]);free(table[1]);free(table[2]);free(table);
    return serie;
    }
    Voici ce que j'obtiens du compilateur:

    Nom : Picture 2.png
Affichages : 463
Taille : 12,7 Ko

    Voici mes questions:

    1 Je n'arrive pas à gérer les lignes blanches. Je croyais que fgets les prenait en charge mais ça donne ce truc bizarre. Comment je peux continuer à lire en ignorant les lignes blanches?

    2 Quand je choisis 1 du menu utilisateur "Rechercher une serie". Le programme ne me renvoit pas la serie:

    Nom : Picture 3.png
Affichages : 358
Taille : 10,1 Ko
    Ce qui me fait comprendre que rien n'est sauvé dans la collection... Pourtant dans ma fonction "lire la collection" j'enregistre bien ma serie et l'ajoute à la fin de la collection?

    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
    while (res!=NULL){
    // detecter une ligne vide
    // if (res==NULL){
    // break;
    // }
     
    serie=creer_serie_depuis_ligne(buff);
    if(serie!=NULL){
    P_un_element_series series_elem=malloc(sizeof(Un_element_series));
    series_elem->element=serie;
    series_elem->suivant=NULL;
    ajouter_serie_a_collection(collectionSeries,series_elem);
    printf("%s\t %s\n", serie->titre, serie->pays_parution);
     
    //lecture de la ligne suivante
    res=fgets(buff, 256, f);
    }
    }
    }
    Du main, le fichier est ouvert:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    P_un_element_series *collectionSeries=malloc(sizeof(Un_element_series));
    char *nom_fichier="collection2.txt";
    lire_collection(collectionSeries,nom_fichier);

    Any help? Merci

  20. #20
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2016
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    J'ai oublié de joindre la fonction "decompose ligne" fourni par l'enseignant:

    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
    char **decompose_ligne(const char *ch, int nb_items) {
      const char *deb = ch;
      int i;
      char **table = malloc(sizeof(char *) * nb_items);
     
      for (i = 0; i < nb_items; i++) {
        while ((*ch != ';') && (*ch != 0)) {
          ch++;
        }
        if (ch > deb) {
          table[i] = malloc((ch - deb + 1) * sizeof(char));
          table[i] = memcpy(table[i], deb, ch - deb);
          table[i][ch - deb] = '\0';
          ch++;
          deb = ch;
        }
        if ((*ch == 0) && (i < nb_items - 1)) {
          // not all items found
          free(table);
          return NULL;
        }
      }
      return table;
    }
    Merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. problème liste simplement chainée
    Par cyrill.gremaud dans le forum C
    Réponses: 9
    Dernier message: 04/12/2012, 15h40
  2. tri par insertion, list simplement chainee
    Par Maf77 dans le forum C
    Réponses: 24
    Dernier message: 12/11/2008, 19h30
  3. Réponses: 2
    Dernier message: 12/10/2007, 11h32
  4. Réponses: 20
    Dernier message: 22/03/2006, 14h00
  5. problème de pointeur avec les listes chainees
    Par innosang dans le forum C
    Réponses: 9
    Dernier message: 30/12/2005, 15h46

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