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 );
}