You are here -> Home linkdd's journals » getopt et le parsage de la ligne de commande en C

getopt et le parsage de la ligne de commande en C

Le 9/11/2009 à 12h22 by linkdd, See the Journals, 0 commentaries

getopt est un header standard disponible sur tout les systèmes Linux/Unix (sous Windows aussi je pense, à vérifier) qui permet un parsage de façon bien simple et très efficace.

Le header getopt est conforme POSIX.

Nous voulons donc parser ceci :

$ ./a.out --help
Usage: ./a.out [option]

Options:
    --help, -h        Aide du programme
    --version -v      Version du programme
    --file, -f <file> Affiche un fichier

La structure option

Nous avons donc besoin d'une structure pour les options longues (--help par exemple), celle ci est définie dans getopt.h :

1
2
3
4
5
6
7
8
#include <getopt.h>

struct option {
    const char *name;    /* nom de l'option */
    int has_arg;         /* définie si l'option requiert un argument, trois valeurs possible : no_argument, required_argument et optional_argument. */
    int *flag;           /* nous ne nous servirons pas de cela, RTFM pour plus d'info  ;)  */
    int val;             /* le manuel ne l'appel pas comme ça, mais je le considère comme l'identifiant de l'option */
};

Initialison notre structure :

1
2
3
4
5
6
static struct option long_options = {
    { "help",    no_argument,       NULL, 'h' },
    { "version", no_argument,       NULL, 'v' },
    { "file",    required_argument, NULL, 'f' },
    { NULL, 0, NULL, 0 }
};

Maintenant nous aurront besoin d'une fonction qui s'occupera du parsage :

1
2
int getopt_long (int argc, char * const *argv, const char *shortopts, const struct option longopts, int *idx);
int getopt (int argc, char * const *argv, const char *shortopts);

Elle retourne l'identifiant de l'option ou -1 si erreur (ou plus d'arguments), on l'utilise donc dans une boucle :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int c;
/* ici le ':' signifie la nécéssité d'un argument */
while ((c = getopt_long (argc, argv, "hvf:", &long_options, NULL)) != -1)
{
    /* c contient l'identifiant de notre option, donc... */
    switch (c)
    {
        case 'h': /* on affiche l'aide */; break;
        case 'v': /* on affiche la version */; break;
        case 'f':
            printf ("file: %s\\n", optarg); /* optarg contient l'argument de notre fonction */
            /* on affiche le fichier */;
            break;
    }
}

Si vous ne désirez pas utiliser les options longues, vous n'avez nul besoin de structure long_options, utilisez la fonction getopt :

1
2
3
4
/* ceci devient... */
while ((c = getopt_long (argc, argv, "hvf:", &long_options, NULL)) != -1)
/* ... cela : */
while ((c = getopt (argc, argv, "hvf:")) != -1)

Désormais amusez vous à parser votre ligne de commande ;)

Commentaries

Author Message