Lihuen
RSSRSS AtomAtom

Diferencia entre revisiones de «Parsear argumentos en forma elegante con getopt()»

 
(No se muestran 5 ediciones intermedias de 2 usuarios)
Línea 1: Línea 1:
Esta es una buena idea para deshacerse de los problemas de parcear los argumentos pasados al main, usando getopt_long()
+
Esta es una buena idea para deshacerse de los problemas de parsear 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
+
Está un poco más claro que en el ejemplo de las páginas del manual y comentado parte por parte.
  
 +
<source lang=c>
 
  #include <stdio.h> /* para printf */
 
  #include <stdio.h> /* para printf */
 
  #include <stdlib.h> /* para exit */
 
  #include <stdlib.h> /* para exit */
 
  #define _GNU_SOURCE
 
  #define _GNU_SOURCE
 
  #include <getopt.h> /*para getopt_long*/  
 
  #include <getopt.h> /*para getopt_long*/  
 
+
 
  int main(int argc, char * argv[]){
 
  int main(int argc, char * argv[]){
int c;
+
    int c;
int digit_optind = 0;
+
    int digit_optind = 0;
 
+
while (1) {
+
    while (1) {
/*Este while parcea todos los argumentos de argv con la funcion getopt_long()*/
+
        /*Este while parsea todos los argumentos de argv con la función getopt_long()*/
int this_option_optind = optind ? optind : 1;
+
        int this_option_optind = optind ? optind : 1;
int option_index = 0;
+
        int option_index = 0;
/*Esta estructura sirve para convertir los argumentos largos en cortos
+
        /*Esta estructura sirve para convertir los argumentos largos en cortos
así, si el argumento es --compress en c se guardara 'c', como c tiene
+
        así, si el argumento es --compress en c se guardará 'c', como c tiene
un argumento opcional, si este existe se guarda en optarg.
+
        un argumento opcional, si éste existe se guarda en optarg.
no_argument, optional_argument y required_argument son macros que se
+
        no_argument, optional_argument y required_argument son macros que se
expanden a 0, 1 y 2 respectivamente*/
+
        expanden a 0, 1 y 2 respectivamente*/
static struct option long_options[] = {
+
        static struct option long_options[] = {
{"compress", optional_argument, 0, 'c'},
+
            {"compress", optional_argument, 0, 'c'},
{"decompress", no_argument, 0, 'd'},
+
            {"decompress", no_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
+
            {"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
+
            {"verbose", no_argument, 0, 'v'},
{"file", required_argument, 0, 'f'},
+
            {"file", required_argument, 0, 'f'},
{0, 0, 0, 0}
+
            {0, 0, 0, 0}
};
+
        };
/*La cadena "dhvf:c::" indica que d, h y v no tienen argumentos, f tiene un
+
        /*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
+
        argumento requerido (por eso los dos puntos 'f:') y c tiene un argumento opcional
(de ahi los dobles dos puntos 'c::')*/
+
        (de ahi los dobles dos puntos 'c::')*/
c = getopt_long (argc, argv, "dhvf:c::",
+
        c = getopt_long (argc, argv, "dhvf:c::",
long_options, &option_index);
+
        long_options, &option_index);
if (c == -1)
+
        if (c == -1)
/*c es -1 cuando se terminan todos los argumentos, entonces sale del while*/
+
        /*c es -1 cuando se terminan todos los argumentos, entonces sale del while*/
break;  
+
        break;  
 
+
switch (c) {  
+
        switch (c) {  
case 'c':
+
            case 'c':
/*Si uno de los argumentos de main es --compress=LZW o -cLZW entra en este case
+
                /*Si uno de los argumentos de main es --compress=LZW o -cLZW entra en este case
c vale 'c' y optarg vale "LZW"*/
+
                c vale 'c' y optarg vale "LZW"*/
printf ("option c");
+
                printf ("option c");
if (0 != optarg)
+
                if (0 != optarg)
printf(" con argumento %s", optarg);
+
                printf(" con argumento %s", optarg);
printf("\n");
+
                printf("\n");
break;  
+
                break;  
 
+
case 'd':  
+
            case 'd':  
/*Si uno de los argumentos de main es --decompress o -d entra en este case*/
+
                /*Si uno de los argumentos de main es --decompress o -d entra en este case*/
printf ("option d\n");
+
                printf ("option d\n");
break;
+
                break;
 
+
case 'h':
+
            case 'h':
/*y asi siguiendo..*/
+
                /*y asi siguiendo..*/
printf ("option h\n");
+
                printf ("option h\n");
break;
+
                break;
 
+
case 'v':
+
            case 'v':
printf ("option v\n");
+
                printf ("option v\n");
break;
+
                break;
 
+
   
case 'f':
+
            case 'f':
printf ("option f con argumento %s\n", optarg);
+
                printf ("option f con argumento %s\n", optarg);
break;
+
                break;
 
+
default:
+
            default:
/*Si el argumento no machea con ninguna opción conocida, debería ser un error en los
+
                /*Si el argumento no machea con ninguna opción conocida, debería ser un error en los
parámetros...*/
+
                parámetros...*/
printf ("La función getopt_long ha retornado un carácter desconocido. El carácter es = %c\n", c);
+
                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...*/
+
        /*Si siguen apareciendo cosas que no son argumentos, se imprimen hasta que se acaben...*/
if (optind < argc) {
+
        if (optind < argc) {
printf ("No son opciones pero estan en ARGV: ");
+
        printf ("No son opciones pero estan en ARGV: ");
while (optind < argc)
+
        while (optind < argc)
printf ("%s ", argv[optind++]);
+
            printf ("%s ", argv[optind++]);
printf ("\n");
+
        printf ("\n");
}
+
      }
exit(0);
+
    exit(0);
 
  }
 
  }
 +
</source>
 +
[[Category:Cátedras]]

Última revisión de 19:34 1 may 2008

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

 #include <stdio.h> /* para printf */
 #include <stdlib.h> /* para exit */
 #define _GNU_SOURCE
 #include <getopt.h> /*para getopt_long*/ 
 
 int main(int argc, char * argv[]){
     int c;
     int digit_optind = 0;
 
     while (1) {
         /*Este while parsea todos los argumentos de argv con la función 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 guardará 'c', como c tiene
         un argumento opcional, si éste 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);
 }