Exercice langage C : Analyser les Paramètres
Écrire un programme qui analyse les paramètres qui lui sont passés. Ce programme devra être appelé de la manière suivante :
exo11 -a chaine1|-b chaine2|-c chaine3 [-d -e -f] fichier
- une seule des options -a, -b ou -c doit être spécifiée, suivie d'une chaîne,
- les options -d, -e, -f sont facultatives. Si aucune d'entre elles n'est indiquée, le programme doit les considérer comme toutes présentes,
- un nom de fichier doit être spécifié.
On essaiera de rendre l'appel le plus souple possible :
- exo11 -a chaîne -e fichier
- exo11 -b chaîne fichier -d -f
- exo11 -c chaîne fichier -df
(regroupement des options -d et -f).
#include
#include
#include
void traitement_option( const unsigned char option );
void usage( char *s );
const unsigned char option_a = 1;
const unsigned char option_b = 2;
const unsigned char option_c = 4;
const unsigned char option_d = 8;
const unsigned char option_e = 16;
const unsigned char option_f = 32;
unsigned char mask_options = 0;
char *valeur_option = NULL, *fichier = NULL;
char *module;
void bilan_options( void );
§MEVBCBfint main( int argc, char **argv )
{
/* Sauvegarde du nom de l'exécutable. */
module = strdup( *argv );
/* Boucle sur les arguments. */
while( *++argv != NULL )
{
/*
* Est-ce que l'argument commence
* par le caractère '-' ?
*/
if( (*argv)[0] == '-' )
{
/* On analyse les caractères qui suivent. */
for( (*argv)++; **argv; (*argv)++ )
{
switch( **argv )
{
case 'a':
traitement_option( option_a );
break;
case 'b':
traitement_option( option_b );
break;
case 'c':
traitement_option( option_c );
break;
case 'd':
traitement_option( option_d );
break;
case 'e':
traitement_option( option_e );
break;
case 'f':
traitement_option( option_f );
break;
default : usage( module );
}
if ( **argv == 'a' || **argv == 'b' || **argv == 'c' )
{
/*
* La valeur de l'option 'a', 'b' ou 'c' peut
* suivre immédiatement, ou bien être séparée
* de l'option par des blancs.
*/
if( *++*argv != '\0' )
valeur_option = strdup( *argv );
/* Cas où aucune valeur ne suit. */
else if( (*++argv)[0] == '-' )
usage( module );
else
valeur_option = strdup( *argv );
break;
}
}
}
/*
* L'argument ne commence pas
* par le caractère '-'.
*/
else if( fichier != NULL )
usage( module );
else
fichier = strdup( *argv );
}
bilan_options();
printf( "\n\nFin EXO11.\n" );
return 0;
}
§MEVBCBfvoid bilan_options( void )
{
/*
* L'option 'a', 'b', ou 'c' suivie d'une
* chaîne, ainsi qu'un nom de fichier
* doivent être spécifiés.
*/
if( valeur_option == NULL || fichier == NULL )
usage( module );
/*
* Si aucune des options 'd', 'e', 'f'
* n'a été spécifiée, on les considère toutes.
*/
if( ! (mask_options & option_d) &&
! (mask_options & option_e) &&
! (mask_options & option_f) )
mask_options |= option_d + option_e + option_f;
if( mask_options & option_a )
printf( "Option \"a\" fournie avec comme valeur : "
"%s\n", valeur_option );
if( mask_options & option_b )
printf( "Option \"b\" fournie avec comme valeur : "
"%s\n", valeur_option );
if( mask_options & option_c )
printf( "Option \"c\" fournie avec comme valeur : "
"%s\n", valeur_option );
printf( "Option \"d\" %s.\n",
mask_options & option_d ? "active" : "inactive" );
printf( "Option \"e\" %s.\n",
mask_options & option_e ? "active" : "inactive" );
printf( "Option \"f\" %s.\n",
mask_options & option_f ? "active" : "inactive" );
printf( "fichier indiqué : %s\n", fichier );
return;
}
§MEVBCBfvoid traitement_option( const unsigned char option )
{
/*
* Une seule des options "-a", "-b", "-c"
* doit avoir été spécifiée.
*/
if ( option == option_a ||
option == option_b ||
option == option_c )
if ( valeur_option != NULL )
usage( module );
/*
* On interdit qu'une option
* soit indiquée 2 fois.
*/
if ( mask_options & option )
usage( module );
else
mask_options |= option;
return;
}
§MEVBCBfvoid usage( char *s )
{
printf( "usage : %s -a chaine | -b chaine"
" | -c chaine [-d -e -f] fichier\n", s );
exit(1);
}