Algo que comúnmente encontramos en sistemas *nix es la ejecución de comandos de este estilo:
$ comando -p --option 5 --option2=5
Donde "-p" y "--option 5" son parámetros que nos permiten modificar el comportamiento de nuestro programa
En lenguaje C se puede implementar de forma bastante primitiva por medio de los argumentos que se reciben en la función main, pero su implementación para lograr la completa funcionalidad sería demasiado larga para un problema tan trivial.
Para esto podemos usar una biblioteca llamada getopt.h, la cual nos permite manipular los parámetros recibidos en la línea de comandos. Para utilizar la versión sencilla se utiliza la función getopt, pero eso permitirá únicamente parámetros cortos del tipo "-p", en cambio si usamos la función getopt_long nos permitirú la ventaja de manipular tanto parámetros cortos (-p) como largos (--option)
El programa mostrado a continuación nos servirá de ejemplo para saber grosso modo como podemos obtener los parámetros recibidos por nuestro programa. Se ha comentaod lo más posible el programa para que sea fácil entender su funcionamiento.
#include <stdio.h>
#include <getopt.h>
int main (int argc, char *argv[])
{
int c; /*Variable utilizada para obtener el parametro actual*/
// Variables bandera para saber si se recibio o no el parametro
int flagaltura = 0, flagbase=0;
// Variables para el calculo del area
float a = 0, b = 0,area=0;
/* Variables para manejar la funcion getopt
optarg = Cadena que guardara el valor para ese parametro
optind = Indice del parametro
optopt = Contiene el parametro en version corta, que se recibio
opterror = Este permitira conocer si hubo algun error en la funcion
long_options = Estructura estatica que guardara los parametros que
se van a recibir, el primer valor es el nombre "largo", el
segundo es si requiere valor, si no, o si es opcional, el
siguiente es la bandera por donde se puede recibir el valor,
comunmente nulo, el ultimo es la version corta del parametro.
option_index = Valor pasado por referencia para controlar la funcion
*/
extern char *optarg;
extern int optind, optopt, opterror;
static struct option long_options[] =
{
{"base", required_argument, 0, 'b'},
{"altura", required_argument, 0, 'a'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
int option_index = 0;
/* Ciclo que controla la lectura de los parametros
Se pasa el numero de parametros recibidos en la linea de comandos (argc)
La lista de las cadenas recibidas (argv)
Una cadena para especificar la forma en que se comportaran los parametros:
a:b:h (Los 2 puntos adelante de las letras significa que esperaran un
valor y la h no recibira ningun valor, notese que es la "version corta"
especificada en long_options)
En caso de que se finalice la lectura de parametros, la funcion regresara
un valor de -1
*/
while ((c=getopt_long(argc, argv, "a:b:h",long_options, &option_index))!=-1)
{
switch(c)
{
case 'b':
// Se imprime el valor recibido de la base
printf ("Base:%s\n",optarg);
// Si se pudo leer su valor numerico se activa la bandera
if (sscanf (optarg,"%f",&b)==1)
flagbase=1;
break;
case 'a':
// Se imprime el valor recibido de la altura
printf ("Altura:%s\n",optarg);
// Si se pudo leer su valor numerico se activa la bandera
if (sscanf (optarg,"%f",&a)==1)
flagaltura = 1;
break;
case 'h':
// Si la opcion es ayuda simplemente se imprime un mensaje y
// se sale del programa
printf ("Parametros:\n\t");
printf ("--base n, -b n : Permite especificar")
printf ("la base del rectangulo\n\t");
printf ("--altura n, -a n : Permite especificar")
printf ("la altura del rectangulo\n\t");
printf ("--help, -h : Muestra este mensaje\n");
return 0; // Se sale del programa, regresando 0 al sistema
break;
case '?':
// Si no se conoce la opcion, se manda un mensaje indicandolo
printf ("Opcion desconocida %c\n", optopt);
break;
}
}
// Si no se pudo obtener la base
// se pide al usuario
if (!flagbase)
{
printf ("Introduzca la base:");
scanf("%f",&b);
}
// Si no se pudo obtener la altura
// se pide al usuario
if (!flagaltura)
{
printf ("Introduzca la altura:");
scanf ("%f",&a);
}
// Se calcula el area
area = b*a;
// Se imprime el area
printf ("El area del rectangulo: %0.2f \n",area);
return 0;
}