Lihuen
RSSRSS AtomAtom

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

(Nueva página: 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 ma...)
 
Línea 2: Línea 2:
 
Esta un poco más claro que en el ejemplo de las paginas del manual y comentado parte por parte
 
Esta un poco más claro que en el ejemplo de las paginas del manual y comentado parte por parte
  
#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 parcea todos los argumentos de argv con la funcion 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 guardara 'c', como c tiene
un argumento opcional, si este existe se guarda en optarg.
+
un argumento opcional, si este 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);
}
+
}

Revisión de 10:28 23 abr 2008

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

#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 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);
}