É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
On essaiera de rendre l'appel le plus souple possible :
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 |
#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); } |