Lihuen
RSSRSS AtomAtom

Parsear argumentos en forma elegante con getopt()

Esta es una buena idea para deshacerse de los problemas de parcear los argumentos pasados al main, usando getopt_long() Esta un poco más claro que en el ejemplo de las paginas del manual y comentado parte por parte

  1. include <stdio.h> /* para printf */
  2. include <stdlib.h> /* para exit */
  3. define _GNU_SOURCE
  4. include <getopt.h> /*para getopt_long*/

int main(int argc, char * argv[]){ int c; int digit_optind = 0;

while (1) { /*Este while parcea todos los argumentos de argv con la funcion getopt_long()*/ int this_option_optind = optind ? optind : 1; int option_index = 0; /*Esta estructura sirve para convertir los argumentos largos en cortos así, si el argumento es --compress en c se guardara 'c', como c tiene un argumento opcional, si este existe se guarda en optarg. no_argument, optional_argument y required_argument son macros que se expanden a 0, 1 y 2 respectivamente*/ static struct option long_options[] = { {"compress", optional_argument, 0, 'c'}, {"decompress", no_argument, 0, 'd'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {"file", required_argument, 0, 'f'}, {0, 0, 0, 0} }; /*La cadena "dhvf:c::" indica que d, h y v no tienen argumentos, f tiene un argumento requerido (por eso los dos puntos 'f:') y c tiene un argumento opcional (de ahi los dobles dos puntos 'c::')*/ c = getopt_long (argc, argv, "dhvf:c::", long_options, &option_index); if (c == -1) /*c es -1 cuando se terminan todos los argumentos, entonces sale del while*/ break;

switch (c) { case 'c': /*Si uno de los argumentos de main es --compress=LZW o -cLZW entra en este case c vale 'c' y optarg vale "LZW"*/ printf ("option c"); if (0 != optarg) printf(" con argumento %s", optarg); printf("\n"); break;

case 'd': /*Si uno de los argumentos de main es --decompress o -d entra en este case*/ printf ("option d\n"); break;

case 'h': /*y asi siguiendo..*/ printf ("option h\n"); break;

case 'v': printf ("option v\n"); break;

case 'f': printf ("option f con argumento %s\n", optarg); break;

default: /*Si el argumento no machea con ninguna opción conocida, debería ser un error en los parámetros...*/ printf ("La función getopt_long ha retornado un carácter desconocido. El carácter es = %c\n", c); } } /*Si siguen apareciendo cosas que no son argumentos, se imprimen hasta que se acaben...*/ if (optind < argc) { printf ("No son opciones pero estan en ARGV: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit(0); }