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 chainées : suppression selon une position


Sujet :

C

  1. #1
    Futur Membre du Club
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Listes chainées : suppression selon une position & listes imbriquées
    bonsoir à tous,
    Je fais présentement appel à vous car voilà plus de deux heures que je me bats avec des listes chainées.
    Je ne vous embèterai pas avec mon énoncé, donc voici le contexte : j'ai une liste chainée, stockant des apparts en location, déclarée comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct app {
      char type[2];
      int ind_proprio;
      reserv *myRes;
      struct app *next;
    }appart;
    Jusque là, rien de bien impressionnant. Cette liste chainée est triée, je n'ai aucun problème avec la fonction d'insertion que j'ai codée.

    Cependant, la suppression me pose problème, car chaque élément de liste chainée n'a pas d'identifiant à proprement parler, ce qui compromet le codage d'une fonction de suppression par recherche d'identifiants.

    Alors j'ai codé une fonction de suppression par position dans la liste chainée, qui est la suivante :
    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
     
    int remAppart(appart **myApparts){
      int id=-1, count = 0;
      appart *apps, *apps2;
     
      apps = *myApparts;
      printf("Saisissez l'identifiant de l'appartement: ");
      fflush(stdin);
      scanf("%d", &id);
      if(id == -1){
        return -1;
      }
      if(id == 0){
        apps = apps->next;
        *myApparts = apps;
        free(apps);
        return 0;
      }
      apps2 = *myApparts;
      apps = apps->next;
      count++;
      while(apps){
        if(count == id){
          apps2->next = apps->next;
          free(apps);
          *myApparts = apps2;
          free(apps2);
          return 0;
        }
        apps = apps->next;
        apps2 = apps2->next;
        count++;
      }
     
      return -2;
    }
    ... Un peu à l'arrache, je vous l'accorde, mais elle devrait fonctionner correctement.
    En fait elle supprime, mais mal. Quand ma liste est remplie de plus de trois apparts, la fonction m'en supprime deux
    Pire : lorsque j'affiche ensuite le contenu, le premier élément voit ses données corrompues

    Je sollicite donc vos talents pour m'aider à trouver ce qui ne va pas dans cette fonction.
    Si cela peut vous aider, voici mon code source complet (mises à part les fonctions que je n'ai pas encore commencées).

    Merci d'avance :-)

    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
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    #define NB_PROP 10
     
    /******************* DECLARATION DES STRUCTURES *******************/
     
    typedef struct res {
      int sem_deb;
      int sem_fin;
      char nom[20];
      struct res *next;
    }reserv;
     
    typedef struct app {
      char type[2];
      int ind_prop;
      reserv *myRes;
      struct app *next;
    }appart;
     
    void clear(){
    #ifdef __WIN32__
      system("CLS");
    #else
      system("clear");
    #endif
    }
     
    void displayMenu(){
      clear();
      printf("..:: LOCATIONS SAISONNIERES ::..\n\n");
      printf("\t0: Sortir ->\n");
      printf("\t1: Ajouter un appartement\n");
      printf("\t2: Ajouter une réservation sur un appartement\n");
      printf("\t3: Supprimer un appartement\n");
      printf("\t4: Supprimer une réservation sur un appartement\n");
      printf("\t5: Afficher les appartements libres\n");
      printf("\t6: Afficher les appartements réservés\n");
      printf("\t7: Afficher tous les appartements\n");
      printf("\nEntrez votre choix\n>");
    }
     
    int addAppart(appart **myApparts){
      appart *apps = *myApparts;
      appart *tmp = NULL;
      appart *myAppart;
      char *type;
      int ind_prop;
     
      type = (char*)malloc(2*sizeof(char));
      /* Saisie des données */
      printf("Saisissez le type d'appartement: ");
      fflush(stdin);
      scanf("%s",type);
      printf("Saisissez l'identifiant du propriétaire: ");
      fflush(stdin);
      scanf("%d", &ind_prop);
      /* Remplissage de l'élément */
      myAppart = (appart*)malloc(sizeof(appart));
      if(!myAppart){
        return -1;
      }
      strcpy(myAppart->type, type);
      myAppart->ind_prop = ind_prop;
      myAppart->myRes = NULL;
      /* Parcours de la liste chaînée */
      while(apps && strcmp(apps->type, type)!=0){
        tmp = apps;
        apps = apps->next;
      }
      /* Création du noeud pour insertion */
      myAppart->next = apps;
      if(tmp){
        tmp->next = myAppart;
      }else{
        *myApparts = myAppart;
      }
      return 0;
    }
     
    int remAppart(appart **myApparts){
      int id=-1, count = 0;
      appart *apps, *apps2;
     
      apps = *myApparts;
      printf("Saisissez l'identifiant de l'appartement: ");
      fflush(stdin);
      scanf("%d", &id);
      if(id == -1){
        return -1;
      }
      if(id == 0){
        apps = apps->next;
        *myApparts = apps;
        free(apps);
        return 0;
      }
      apps2 = *myApparts;
      apps = apps->next;
      count++;
      while(apps){
        if(count == id){
          apps2->next = apps->next;
          free(apps);
          *myApparts = apps2;
          free(apps2);
          return 0;
        }
        apps = apps->next;
        apps2 = apps2->next;
        count++;
      }
     
      return -2;
    }
     
    int affApparts(appart **myApparts, char **props, int mode){
      appart *apps = *myApparts;
      int count = 0, choice;
      switch(mode){
      case 0: /* Tous les apparts */
        while(apps){
          clear();
          printf("--> Appartement N°%d\n", count);
          printf("\tType:\t%s\n", apps->type);
          printf("\tPropriétaire:\n\t%s", props[apps->ind_prop]);
          printf("\n");
          printf("1: Appartement suivant\n0: Sortir\n>");
          scanf("%d", &choice);
          if(choice == 1){
    	apps = apps->next;
    	count++;
          }else{
    	return 0;
          }
        }
        break;
      case 1: /* Apparts libres */
     
        break;
      case 2: /* Apparts réservés */
     
        break;
      default:
        return -1;
      }
      return 0;    
    }
     
    void init_props(char **props){
      props[0] = "prop0";
      props[1] = "prop1";
      props[2] = "prop2";
      props[3] = "prop3";
      props[4] = "prop4";
      props[5] = "prop5";
    }
     
    /******************* FONCTION MAIN *******************/
     
    int main(){
      char **props;
      appart *myApparts=NULL;
      int choice;
     
      props = (char**)malloc(NB_PROP*sizeof(char*));
      if(!props){
        return EXIT_FAILURE;
      }
      init_props(props);
      while(1){
        displayMenu();
        scanf("%d", &choice);
        switch(choice){
        case 0:
          clear();
          return EXIT_SUCCESS;
          break;
        case 1:
          if(addAppart(&myApparts) < 0){
    	perror("Erreur lors de l'ajout du nouvel appartement");
    	sleep(2);
          }
          break;
        case 2:
     
          break;
        case 3:
          remAppart(&myApparts);
          break;
        case 4:
     
          break;
        case 5:
          affApparts(&myApparts, props, 1);
          break;
        case 6:
          affApparts(&myApparts, props, 2);
          break;
        case 7:
          affApparts(&myApparts, props, 0);
          break;
        }
      }
     
      return EXIT_SUCCESS;
    }

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Tu dis que ta liste chainée est triée. Comment fais-tu pour effectuer ce tri si dis que les éléments ne possèdent pas d'identificateurs?

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Cependant, la suppression me pose problème, car chaque élément de liste chainée n'a pas d'identifiant à proprement parler, ce qui compromet le codage d'une fonction de suppression par recherche d'identifiants.
    Tu n'aurais pas un petit problème de conception là ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      if(id == 0){
        apps = apps->next;
        *myApparts = apps;
        free(apps);
        return 0;
      }
    Là tu as un gros problème : que fais-tu ?
    apps = apps->next;
    Ici tu perds l'adresse de l'ancien apps, donc fuitemémoire.
    Tu fais pointer *myApparts sur la nouvelle adresse de apps ... que tu t'empresses ensuite de libérer par un free, l'adresse est donc invalide et *myApparts pointe dans le décor.
    Il faut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     if(id == 0){
        *myApparts = apps->next;
        free(apps);
        return 0;
      }
    Tu as le même problème ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        if(count == id){
          apps2->next = apps->next;
          free(apps);
          *myApparts = apps2;
          free(apps2);
          return 0;
        }
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Quelques remarques en vitesse...

    Je n'aime pas le scanf au plein milieu d'un code d'algorithmique. Passe l'index en paramètre de ta fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         apps = apps->next;
        *myApparts = apps;
        free(apps);
    Déjà là je ne comprends pas. Tu prends l'élément suivant OK, tu l'affectes à ta valeur de retour OK et tu la libères au lieu de faire le free sur le premier élément.

    free(apps);
    *myApparts = apps2;
    free(apps2);
    Tu fais deux free pour libérer un élément pas bon.

  5. #5
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Voici quelques commentaires directement dans le 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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    #define NB_PROP 10
     
    /******************* DECLARATION DES STRUCTURES *******************/
     
    typedef struct res
    {
        int sem_deb;
        int sem_fin;
        char nom[20];
        struct res *next;
    } reserv;
     
    typedef struct app
    {
        char type[2];
        int ind_prop;
        reserv *myRes;
        struct app *next;
    } appart;
     
    void clear(void)
    {
    #ifdef __WIN32__
        system("CLS");
    #else
        system("clear");
    #endif
    }
     
    void displayMenu(void)
    {
        clear();
        printf("..:: LOCATIONS SAISONNIERES ::..\n\n");
        printf("\t0: Sortir ->\n");
        printf("\t1: Ajouter un appartement\n");
        printf("\t2: Ajouter une réservation sur un appartement\n");
        printf("\t3: Supprimer un appartement\n");
        printf("\t4: Supprimer une réservation sur un appartement\n");
        printf("\t5: Afficher les appartements libres\n");
        printf("\t6: Afficher les appartements réservés\n");
        printf("\t7: Afficher tous les appartements\n");
        printf("\nEntrez votre choix\n>");
    }
     
    /* -tc- Purge le tampon du flux entrant pointe par fp*/
    void fpurge(FILE *fp)
    {
        if (fp != NULL)
        {
            int c;
     
            while ((c = fgetc(fp)) != '\n' && c != EOF)
            {
            }
        }
    }
     
    /* -tc- Verifie si la saisie effectuee avec fgets() a ete tronquee, elimine le
       le caractere de fin de ligne terminant la saisie et purge le flux entrant
       pointe par fp si necessaire */
    void fclean(char *buffer, FILE *fp)
    {
        if (buffer != NULL && fp != NULL)
        {
            char *pc = strchr(buffer, '\n');
     
            if (pc != NULL)
            {
                *pc = 0;
            }
            else
            {
                fpurge(fp);
            }
        }
    }
     
    int addAppart(appart **myApparts)
    {
        /* -tc- A ce stade, il faudrait tester que myAppart  != NULL */
        appart *apps = *myApparts;
        appart *tmp = NULL;
        appart *myAppart;
        int rv = 0;
        char *type;
        /* -tc- Si tu alloue dynamiquement la memoire pour le tampon type (ce qui
           n'est pas necessaire ici), je prefere stocker la taille du tampon dans
           une variable plutot que de la coder en dur dans l'appel a malloc().
           Cela facilite la maintenance et les appels futurs a fgets() pour la saisie */
        size_t type_size = 2;
        int ind_prop;
     
        /* -tc- Il n'est pas necessaire, voir meme deconseille de caster la valeur
           retournee par malloc: type = (char *)malloc(2*sizeof(char));
           Toutefois, la taille du champ type de la structure appart est connue,
           je ne vois pas pourquoi l'allocation dynamique est necessaire ici
     
           Par ailleurs, sizeof (char) vaut 1 par definition. Je prefere utiliser
           sizeof *type qui a l'avantage de faciliter la maintenance */
        type = malloc(type_size * sizeof *type);
        /* -tc- Il faut TOUJOURS tester la valeur retournee par malloc(). Par ailleurs,
           tu as pris le parti de gerer les erreurs en sortant de la fonction avec
           plusieurs instructions return. Un des principes fondamentaux de la
           programmation structuree est d'avoir un et un seul point de sortie par
           fonction */
        if (type == NULL)
        {
            return -1;
        }
        /* Saisie des données */
        printf("Saisissez le type d'appartement: ");
        /* -tc- fflush() engendre un comportement indefinit lorsqu'il est utilise avec
           un flux entrant. Par contre, a ce point du programme, il est necessaire
           d'appeler fflush(stdout) pour forcer l'affichage de l'invite */
        fflush(stdout);
        /* Cette utilisation de scanf() est une des pires qu'on peut imaginer*/
        fgets(type, type_size, stdin);
        puts(type);
        /* -tc- fclean() est la fonction a utiliser pour nettoyer le tampon du flux
           d'entree standard apres utilisation de fgets(). Pour plus d'info sur cette
           fonction, voir les archives du forum */
        fclean(type, stdin);
        /* -tc- Je suis de ceux qui pensent qu'on ne devrait jamais utiliser scanf(),
           mais voici comment realiser la saisie suivante correctement */
        do
        {
            printf("Saisissez l'identifiant du propriétaire: ");
            /* -tc- vider le tampon du flux de sortie standard */
            fflush(stdout);
            rv = scanf("%d", &ind_prop);
            fpurge(stdin);
        }
        while (rv != 1 || ind_prop < 0 || ind_prop >= NB_PROP);
     
        /* Remplissage de l'élément */
        /* -tc- Une nouvelle fois, le cast est inutile et je prefere remplacer
           sizeof (appart) par sizeof *myAppart */
        myAppart = malloc(sizeof *myAppart);
        if (!myAppart)
        {
            return -1;
        }
        strcpy(myAppart->type, type);
        myAppart->ind_prop = ind_prop;
        myAppart->myRes = NULL;
        /* Parcours de la liste chaînée */
        while (apps && strcmp(apps->type, type)!= 0)
        {
            tmp = apps;
            apps = apps->next;
        }
        /* Création du noeud pour insertion */
        myAppart->next = apps;
        if (tmp)
        {
            tmp->next = myAppart;
        }
        else
        {
            *myApparts = myAppart;
        }
     
        /* -tc- Ne pas oublier de liberer la memoire allouee pour type */
        free(type), type = NULL;
        return 0;
    }
     
    int remAppart(appart **myApparts)
    {
        /* -tc- C'est une question de preference personnelle, mais ca me donne mal
           a la tete lorsque que j'ai plusieurs definitions/initialisations par ligne */
        int id = -1;
        int count = 0;
        appart *apps = NULL;
        appart *apps2 = NULL;
        appart *tmp = NULL;
        int rv = 0;
     
        /* -tc- tester que myApparts != NULL && *myApparts != NULL */
        apps = *myApparts;
        /*-tc- modification pour utilisation propre de scanf() */
        do
        {
            printf("Saisissez l'identifiant de l'appartement: ");
            /* -tc- C'est toujours le flux de sortie qu'il faut purger ici */
            fflush(stdout);
            rv = scanf("%d", &id);
            fpurge(stdin);
        }
        while (rv != 1);
     
        if (id == -1)
        {
            return -1;
        }
        /* -tc- C'est ce qu'on appelle scier la branche sur laquelle on est assis.
           Ici, tu libère le 2eme element de la chaine. *myApparts ne POINTE PLUS sur
           une adresse valide.
        if (id == 0)
        {
            apps = apps->next;
            *myApparts = apps;
            free(apps);
            return 0;
        }
        */
        if (id == 0)
        {
            tmp = apps;
            apps = apps->next;
            *myApparts = apps;
            free(tmp), tmp = NULL;
            return 0;
        }
     
        apps2 = *myApparts;
        apps = apps->next;
        count++;
        while (apps)
        {
            if (count == id)
            {
                apps2->next = apps->next;
                free(apps);
                /* -tc- Liberer l'appart pointe par apps, oui! Pourquoi modifier
                   *myApparts et liberer l'adresse sur laquelle elle pointe. Cela
                   n'a pas de sens
                *myApparts = apps2;
                free(apps2);
                */
                return 0;
            }
            apps = apps->next;
            apps2 = apps2->next;
            count++;
        }
     
        /* Si tu desire utiliser plusieurs codes d'erreur pour effectuer une gestion
           fine, tu devrais utiliser des constantes symboliques. Cela rendra le
           code plus lisible */
        return -2;
    }
     
    int affApparts(appart **myApparts, const char **props, int mode)
    {
        /* -tc- SI myApparts est NULL, que ce passe-t'il ici? */
        appart *apps = *myApparts;
        int count = 0, choice;
        int rv = 0;
        switch (mode)
        {
        case 0: /* Tous les apparts */
            while (apps)
            {
                clear();
                printf("--> Appartement N°%d\n", count);
                printf("\tType:\t%s\n", apps->type);
                printf("\tPropriétaire:\n\t%s", props[apps->ind_prop]);
                printf("\n");
                /* -tc- code de la saisie modifie */
                do
                {
                    printf("1: Appartement suivant\n0: Sortir\n>");
                    fflush(stdout);
                    rv = scanf("%d", &choice);
                    fpurge(stdin);
                }
                while (rv != 1 || choice != 1 || choice != 0);
     
                if (choice == 1)
                {
                    apps = apps->next;
                    count++;
                }
                else
                {
                    return 0;
                }
            }
            break;
        case 1: /* Apparts libres */
     
            break;
        case 2: /* Apparts réservés */
     
            break;
        default:
            return -1;
        }
        return 0;
    }
     
    void init_props(const char **props)
    {
        props[0] = "prop0";
        props[1] = "prop1";
        props[2] = "prop2";
        props[3] = "prop3";
        props[4] = "prop4";
        props[5] = "prop5";
    }
     
    /******************* FONCTION MAIN *******************/
     
    int main(void)
    {
        const char **props = NULL;
        appart *myApparts = NULL;
        int rv = 0;
        int choice;
     
        /* -tc- cast inutile et judicieux de remplacer sizeof (char*) par sizeof *props */
        props = malloc(NB_PROP * sizeof(char*));
        if (!props)
        {
            /* -tc- On utilise generalement exit() pour terminer prematurement le
               programme*/
            exit(EXIT_FAILURE);
        }
        /* -tc- pourquoi init_props() n'initialise que 5 proprietaires et non NB_PROP */
        init_props(props);
        while (1)
        {
            /* -tc- J'ai mis plein d'exemplete permettant d'utiliser scanf() proprement
               plus haut */
            do
            {
                displayMenu();
                rv = scanf("%d", &choice);
                fpurge(stdin);
            }
            while (rv != 1 || choice < 0 || choice > 7);
     
            switch (choice)
            {
            case 0:
                clear();
                return EXIT_SUCCESS;
                break;
            case 1:
                if (addAppart(&myApparts) < 0)
                {
                    perror("Erreur lors de l'ajout du nouvel appartement");
                    sleep(2);
                }
                break;
            case 2:
     
                break;
            case 3:
                remAppart(&myApparts);
                break;
            case 4:
     
                break;
            case 5:
                affApparts(&myApparts, props, 1);
                break;
            case 6:
                affApparts(&myApparts, props, 2);
                break;
            case 7:
                affApparts(&myApparts, props, 0);
                break;
            }
        }
     
        return EXIT_SUCCESS;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  6. #6
    Futur Membre du Club
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Comment fais-tu pour effectuer ce tri si dis que les éléments ne possèdent pas d'identificateurs?
    Et bien la liste est triée seulement par le type d'appartement.

    Sinon, je n'ai pas de problème de conception, mon énoncé était on-ne-peut-plus clair.
    C'est au niveau de la prog où, effectivement, j'ai un blème (toujours eu du mal avec les listes chainées).

    En tout cas, merci pour vos conseils :-)

    Trap D, je vais faire ce que tu m'as dit, ça devrait marcher mieux par la suite.
    aoyou, tu as raison, j'avais pris une mauvaise décision en voulant faire un Main dénué de scanf. Je vais de ce pas les déplacer.
    [edit]Merci mille fois, Thierry, pour tes commentaires, je vais les prendre en compte :-)

  7. #7
    Futur Membre du Club
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Voilà, je viens de refaire mes fonctions et tout roule ! Merci encore, c'est très sympa à vous de m'avoir aidé !

    Cependant un hic demeure, je suis entièrement d'accord avec toi sur scanf, Thierry, mais si je l'utilisais c'est parce que fgets ne faisait pas l'arrêt escompté mais elle zappait tout simplement la saisie (sinon je l'aurait utilisée à outrance).
    J'ai été particulièrement enchanté par ta solution pour pouvoir zapper scanf avec fgets, cependant la saisie de la chaine "type" n'est... pas enregistrée.

    Les chaines type dans chaque structure demeurent vides, je n'ai pas encore réussi à en déterminer la raison et pourtant j'ai fait exactement comme tu me l'as suggéré.
    J'ai bien analysé le tout et je n'ai pas vu d'erreurs. J'vais continuer à regarder, si ça se trouve c'est un truc tout con.

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Le problème ne venait pas de mon utilisation de fgets(), mais de du scanf() que TU utilises dans main(). Tu ne purgeais pas le tampon de stdin après la saisie. Voilà un exemple typique des problèmes que peuvent engendrer un tel oubli...

    J'ai mis à jour le code proposé ici.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Futur Membre du Club
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Je n'ai jamais remis en cause ton utilisation de fgets, mais plutôt MA manière d'interpréter ton code.
    D'abord j'avais oublié de jarter le cast avant le malloc sur "type".
    Ensuite fgets était zappé, comme d'hab... Alors j'ai trouvé le truc qui n'allait pas, en mettant un fgetc(stdin) avant le fgets tout marche niquelle.

    Merci beaucoup !

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par NaPaLM Voir le message
    Je n'ai jamais remis en cause ton utilisation de fgets, mais plutôt MA manière d'interpréter ton code.
    D'abord j'avais oublié de jarter le cast avant le malloc sur "type".
    Ensuite fgets était zappé, comme d'hab... Alors j'ai trouvé le truc qui n'allait pas, en mettant un fgetc(stdin) avant le fgets tout marche niquelle.

    Merci beaucoup !
    C'est plus intelligent de nettoyer le tampon de stdin après chaque saisie, plutôt que de procéder comme tu le fais...

    Relis une fois le code que j'ai mis à jour ici.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  11. #11
    Futur Membre du Club
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Oops désolé
    J'avais pas vu ta modif du scanf qui était dans le main()... Je ne suis pas partisant du copier-coller, j'aime analyser ce que j'écris... Je devais donc être un peu mal réveillé..
    Quoi qu'il en soit fgets marche sans mon vieux fgetc(stdin) avant et tout roule bien.

    Mille mercis à vous qui m'avez aidé à résoudre ce problème et, de surcroît, appris que j'ai de sacrés progrès à faire en C.

    à la revoyure

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

Discussions similaires

  1. Réponses: 15
    Dernier message: 25/07/2014, 17h29
  2. Réponses: 3
    Dernier message: 30/03/2007, 18h03
  3. Réponses: 8
    Dernier message: 01/04/2006, 10h10
  4. Réponses: 4
    Dernier message: 26/09/2005, 22h36
  5. liste chainée :suppression milieu par rapport à un caractère
    Par Pouyou le caribou dans le forum C++
    Réponses: 4
    Dernier message: 06/06/2005, 18h49

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