Don’t Be shy, let me know your choices, getopt();
Cuando se escriben programas para línea de comandos (programas de consola) es muy común tener que implementar una forma de parametrizar dicho programa al inicio, esto se logra pasando argumentos en la linea de comandos (Unix) al momento de ejecutar nuestro programa, en un principio solía escribir todo el código necesario para reconocer todos y cada uno de los argumentos, esto implicaba tener que recorrer un String analizando si existía en determinado String cada uno de los flags permitidos por el programa y analizar si el valor de dicho flag era valido para ese mismo flag, si bien esa tarea no es difícil si que es tediosa (al menos para mi que no me gustan las tareas repetitivas). Afortunadamente si estamos escribiendo nuestro programa en lenguaje C contamos con la función getopt() de la librería <unistd.h> que nos simplificará muchísimo la tarea.
La funcion getopt(); tiene la siguiente sintaxis:
int getopt(int argc, char * const argv[], const char *optstring);
Donde argc es un entero que representa el número de argumentos pasados al metodo main, *argv[] es el array de Strings pasados al metodo main, y *optstring es un String que representa la configuración de que flags espera procesar la fución getopt() y si dichos flags deben tener un valor asociado o no.
La funcion getopt() regresa un entero que representa la opción actualmente procesada o -1 en caso de haber terminado de analizar todo el array de Strings determinado por el parametro *argv[], cada vez que la función es llamada se incrementa un indice interno que apunta a los diferentes elementos del array de Strings determinado por el argumento *argv[].
Ademas de lo anterior, la funcion getopt(); establece las siguientes variables externas:
extern char *optarg; extern int optind; extern int optopt; extern int opterr; extern int optreset;
- *optarg: Contiene el valor asociado a determinado flag si se ha espesificado que dicho flag admite valores, es decir, si se analiza el siguiente flag -f archivo.txt, *optarg contendra el valor archivo.txt
- optind: Contiene el indice del siguiente flag que se analizará en la siguiente llamada a la funcion getopt();
- optopt: Contiene el flag que actualmente esta siendo procesado.
- opterr: Si la función getopt(); encuentra un caracter que no esta espesificado en la cadena *optstring o detecta que falta el valor de un flag que debe tener un valor asociado escribira un mensaje de error en el flujo de salida stderr y retornara un valor ‘?’, para desactivar el mensaje de error en el flujo stderr tenemos que establecer el valor de opterr a 0 (cero).
- optreset: Es utilizada si queremos evaluar multiples grupos de argumentos o un grupo simple multiples veces.
Para indicar a la función getopt(); que flags debe reconocer y si esos flags tienen valores asociados debemos pasar un valor en forma de cadena al argumento *optstring, el valor de dicha cadena deben ser caracteres individuales representando a cado uno de los flags, un caracter independiente seguido de dos puntos indica que ese flag debe tener un valor asociado, de tal forma que:
"abc"reconocerá los flags de la forma -a -b -c
y la cadena
"ab:c"reconocerá los flags de la forma -a -b valor -c
ejemplo:
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 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <unistd.h> void usage(); int main ( int argc, char *argv[] ) { char *host; int flagx; int ch; host = NULL; flagx = false; while( ( ch=getopt( argc, argv, "xh:" ) ) != -1 ) { switch( ch ) { case 'x': flagx = true; break; case 'h': host = (char *)malloc( strlen( optarg+1 ) ); bzero( host, strlen( optarg+1 ) ); strcpy( host, optarg ); break; case '?': usage(); return 0; break; } } printf( "-x = %d\n", flagx ); printf( "-h = %s\n", host ); free( host ); return 1; } void usage() { printf( "forma de uso:\n\t-x\n\t-h [nombre host|ip host]\n\n" ); } |
aquí el resultado:
[espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x = 0 -h = (null) [espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x -x = 1 -h = (null) [espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x -h example.org -x = 1 -h = example.org [espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -h example.org -x -x = 1 -h = example.org [espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x -h example.org -d getoptexamble: illegal option -- d forma de uso: -x -h [nombre host|ip host] [espartano@moscu ~/programas/C/pruebas]$
Para mas informacion pueden leer la pagina del manual de la función getopt(), man 3 getopt.






