Exercice langage C corrigé gestion d’une liste chaînée

Fichier exo19.h

#define taille(t) sizeof(t) / sizeof(t[0])
typedef enum bool {False, True} Boolean;

Fichier exo19_gestion_liste.h

void ajouts     ( void );
void liste      ( void );
void tri        ( void );
void suppression( void );
void vider      ( void );
void arret      ( void );

Fichier exo19.c

#include 
#include 
#include 
#include "exo19.h"
#include "exo19_gestion_liste.h"

struct menu
{
  char  *texte;
  void (*action)( void );
};

§MEVBCBfint main()
{
  /* Définition du menu. */
  struct menu menu[] =
  {
    {"  1 - AJOUTS d'éléments dans une liste chaînée.\n",
                                                 ajouts},
    {"  2 - AFFICHAGE de la liste chaînée.\n",
                                                  liste},
    {"  3 - TRI de la liste chaînée.\n",
                                                    tri},
    {"  4 - SUPPRESSION d'éléments dans la liste.\n",
                                            suppression},
    {"  5 - VIDER la liste.\n",
                                                  vider},
    {"  6 - ARRÊT du programme.\n",
                                                  arret}
  };

  int SelectionMenu( struct menu menu[], int NbChoix );

  /* Boucle infinie sur les choix effectués. */
  for (;;)
    menu[SelectionMenu( menu, taille(menu) )].action();
}

 /* Fonction renvoyant le choix effectué. */

§MEVBCBfint SelectionMenu( struct menu menu[], int NbChoix )
{
  int   choix, m;
  char  entree[10];
  char *endp;

  do
  {
    printf( "\n\nListe des choix :\n" );
    for( m=0; m NbChoix )
      printf( "\nERREUR - choix invalide.\n" );
  } while( *endp != '' ||
           choix < 1 || choix > NbChoix );
  printf("\n");

  return --choix;
}

Fichier exo19_gestion_liste.c

#include 
#include 
#include 
#include "exo19.h"
#include "exo19_gestion_liste.h"

#define LISTE_VIDE "La liste est vide.\n"

static const char * const prompt_ajout       =
     "Élément à ajouter[CtrlD pour terminer] --> ";
static const char * const prompt_suppression =
     "Élément à supprimer[CtrlD pour terminer] --> ";
static const char *prompt;

typedef struct cellule
{
  char           *capitale;
  struct cellule *ptr_precedent;
  struct cellule *ptr_suivant;
} CEL;

static CEL  *debut   = NULL;
static CEL  *curseur = NULL;

static Boolean  liste_vide( void );
static void     ajout_cellule( char *chaine );
static void     suppression_cellule( void );
static Boolean  recherche_cellule( char *chaine );
static char    *lire_chaine( void );
static void     affichage_liste( CEL *p );

§MEVBCBfstatic Boolean liste_vide( void )
{
  return debut == NULL ? True : False;
}

§MEVBCBfstatic void ajout_cellule( char *chaine )
{
  CEL *p;

  /*
   * Allocation, valorisation,
   * insertion du nouvel élément.
   */

  p = malloc( sizeof(CEL) );
  p->capitale = chaine;

  if ( liste_vide() )
    p->ptr_suivant = p->ptr_precedent = NULL;
  else
  {
    if ( curseur != debut )
      curseur->ptr_precedent->ptr_suivant = p;
    p->ptr_precedent = curseur->ptr_precedent;
    curseur->ptr_precedent = p;
    p->ptr_suivant = curseur;
  }
  curseur = p;
  if( curseur->ptr_precedent == NULL )
    debut = curseur;

  return;
}

 §MEVBCBfstatic void suppression_cellule( void )
{
  if( curseur == debut )
  {
    /*
     * L'élément à supprimer est le 1er de la liste.
     */

    debut = curseur->ptr_suivant;
    if( ! liste_vide() )
      debut->ptr_precedent = NULL;
  }
  else
  {
    /*
     * L'élément à supprimer n'est pas le 1er de la liste.
     */

    curseur->ptr_precedent->ptr_suivant =
                          curseur->ptr_suivant;
    if( curseur->ptr_suivant != NULL )
      /*
       * L'élément à supprimer n'est
       * pas le dernier de la liste.
       */
      curseur->ptr_suivant->ptr_precedent =
                          curseur->ptr_precedent;
  }

   {
    CEL *p = curseur;

    free( p->capitale ); free( p );
    if ( curseur->ptr_suivant != NULL )
      curseur = curseur->ptr_suivant;
    else
      curseur = debut;
  }

  return;
}

§MEVBCBfstatic Boolean recherche_cellule( char *chaine )
{
  CEL *p;

  for( p=debut; p; p=p->ptr_suivant )
    if ( ! strcmp( p->capitale, chaine ) )
      break;

  if( p != NULL )
  {
    curseur = p;
    return True;
  }

  return False;
}

 §MEVBCBfstatic char *lire_chaine( void )
{
  char buffer[BUFSIZ];

  /*
   * Lecture de l'élément à ajouter.
   */

  fputs( prompt, stdout );
  gets( buffer );

  /*
   * Si Control-D, annuler le bit indicateur
   * de fin de fichier, pour les prochaines saisies.
   */

  if( feof( stdin ) )
  {
    clearerr( stdin );
    return NULL;
  }

  return strdup( buffer );
}

 /*
 * Fonction rattachée au choix 1.
 * (AJOUTS d'éléments dans la liste chaînée).
 */

§MEVBCBfvoid ajouts( void )
{
  char *chaine;

  /*
   * Boucle de lecture des chaînes.
   */

  prompt = prompt_ajout;

  while( (chaine = lire_chaine()) != NULL )
    ajout_cellule( chaine );

  return;
}

 /*
 * Fonction rattachée au choix 3.
 * (TRI de la liste chaînée).
 */

§MEVBCBfvoid tri( void )
{
  Boolean  tri_terminee;
  CEL     *ptr;

  /*
   * La liste doit exister.
   */

  if ( liste_vide() )
    fprintf( stderr, LISTE_VIDE );
  else
  {
    /*
     * Boucle de tri.
     */

     do
    {
      tri_terminee = True;
      for( ptr=debut; ptr->ptr_suivant;
           ptr = ptr->ptr_suivant )
        if( strcmp( ptr->capitale,
                    ptr->ptr_suivant->capitale ) > 0 )
        {
          /*
           * On effectue une interversion.
           */

          curseur = ptr;
          ajout_cellule(
            strdup( curseur->ptr_suivant->capitale ) );
          curseur = ptr->ptr_suivant;
          suppression_cellule();
          tri_terminee = False;
          if ( ptr->ptr_suivant == NULL )
            break;
        }
    } while( ! tri_terminee );
  }

  return;
}

 /*
 * Fonction rattachée au choix 4.
 * (SUPPRESSION d'éléments dans la liste).
 */
§MEVBCBfvoid suppression( void )
{
  char *chaine;

  /*
   * Boucle de lecture des chaînes.
   */
  prompt = prompt_suppression;

  while( ! liste_vide() && (chaine = lire_chaine()) != NULL )
  {
    if( ! recherche_cellule( chaine ) )
    {
      fprintf( stderr, "L'élément \"%s\" est"
                       " inexistant!\n\n", chaine );
      continue;
    }
    suppression_cellule();
    printf( "L'élément \"%s\" a été supprimé"
            " de la liste.\n\n", chaine );
  }

  /*
   * La liste est-elle vide ?
   */
  if ( liste_vide() ) fprintf( stderr, LISTE_VIDE );

  return;
}

 /*
 * Fonction rattachée au choix 5.
 * (VIDER la liste ).
 */
§MEVBCBfvoid vider( void )
{
  if ( liste_vide() )
    fprintf( stderr, LISTE_VIDE );
  else
  {
    curseur = debut;
    while ( ! liste_vide() )
      suppression_cellule();
  }

  return;
}
/*
 * Fonction rattachée au choix 6.
 * (ARRET du programme).
 */
§MEVBCBfvoid arret( void )
{
  /*
   * Si la liste n'est pas vide, on libère
   * la mémoire qu'elle occupe.
   */
  if( ! liste_vide() ) vider();

  printf( "\n\nFin EXO19.\n" );

  exit( 0 );
}

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *