Vamos la \o
Para implementar o processamento da linha de comando em seus programas você pode usar as funções getopt() e getopt_long().
A função getopt() faz parte do arquivo de cabeçalho unistd.h e sua sintaxe é:
#include <unistd.h>
int getopt(int argc, char *argv[], char *opcoes)
extern *optarg;
extern optind;
extern opterrr;
onde argc e argv são os conhecidos argumentos de main e opcoes é uma string que armazena os caracteres de opção suportados pelo programa. A definição de opcoes deve ser algo como:
static char opcoes[] = "ab:c";
Observe que a letra b vem seguida de dois pontos. Isto indica que esta opção pode receber argumentos, o que não ocorre com as opções a e c.
A função getopt() ainda possui três variáveis externas que devem ser conhecidas pois serão utilizadas:
* optarg é uma variável ponteiro que aponta para o argumento da opção, caso esta aceite. Assim, se getopt estiver processando uma opção do tipo -Wall ou -W all, a variável optarg apontará para all.
* optind é uma variável inteiro que inicia com o valor 1. Ela é usada por getopt para apontar para os argumentos passados na linha de comando. Como inicia com o valor 1, getopt processa a partir de argv[1]. No final do procesamento de getopt esta variável estará apontando para o primeiro argumento do programa. Por exemplo, se sua linha de comando é:
exemplo -v teste
ao final do processamento desta linha, optind estará apontando para o argumento teste.
* opterr é uma variável que exibe ou não mensagens de erro padrão quando uma opção não definida na string opcoes é passada. Ela é inicializada com o valor 1 indicando TRUE. Quando ela tem este valor e um caractere não definido em opcoes é passado, uma mensagem de erro padrão é exibida em stderr, que normalmente é o monitor. Quando opterr é configurada como 0 (zero) por seu programa, indicando FALSE, a mensagem de erro padrão não é exibida se um caractere não definido em opcoes for passado. Isto é feito quando seu programa fornecer a mensagem de erro ou quando a mensagem deve ir para outro lugar em vez de stderr.
getopt funciona da seguinte maneira:
A linha de comando é analisada e a função retorna um valor inteiro. Cada chamada da função retorna um dos caracteres de opção passados. Ao retornar o caractere de opção, a variável optarg aponta para o argumento da opção, caso este exista. Ao final da análise, o valor -1 é retornado pela função. Neste ponto optind estará apontando para o primeiro argumento do programa. Por exemplo, digamos que a linha de comando a ser processada por getopt seja:
gcc -Wall -g arquivo.c
a coisa funciona assim:
1. getopt é chamada, analisa a linha de comando e retorna W. Como esta opção aceita argumentos e um argumento foi passado, optarg aponta para all.
2. getopt é chamada novamente e agora retorna g.
3. o processamento das opções termina e getopt retorna -1. optind estará com o valor 3 indicando que o primeiro argumento do programa é argv[3].
Para um melhor entendimento vamos a um exemplo usando getopt:
/* Processando opções da linha de comando com getopt() */
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int opcao;
static char opcoes[] = "ab:c";
opterr = 0;
while((opcao = getopt(argc,argv,opcoes)) != -1)
switch(opcao)
{
case 'a':
{
printf("opção -a escolhida.\n");
break;
}
case 'b':
{
printf("opção -b escolhida.\n");
printf("esta opção recebeu o argumento %s.\n",optarg);
break;
}
case 'c':
{
printf("opção -c escolhida.\n");
break;
}
default:
printf("opção inválida!\n");
}
for(;optind < argc;optind++)
printf("argv[%d] = %s\n",optind,argv[optind]);
return(0);
}
getopt_long()
Com getopt_long você pode processar opções longas tipo -- version. Esta função faz parte do arquivo de cabeçalho getopt.h e sua sintaxe é:
#include <getopt.h>
int getopt_long(int argc, char *argv[],
char *opcoes,
option *opcoes_longas,
int *indice_opcoes_longas)
onde argc, argv e opcoes já são conhecidos. opcoes é uma string do tipo daquela mostrada no uso de getopt() acima.
O argumento opcoes_longas é um ponteiro para uma matriz de estruturas do tipo option. Esta estrutura é pré-definida em getopt.h e sua composição é:
struct option
{
const char *name;/* Nome da opção longa */
int has_arg; /* Diferente de zero se opção aceita argumento */
int *flag; /* NULL(zero) ou um ponteiro para um valor int */
int val; /* Valor de retorno */
}
Abaixo segue um exemplo de como deve ser a declaração da matriz de estruturas do tipo option a ser usada com getopt_long:
static struct option opcoes_longas[]=
{
{"help",0,0,'h'}, /* name,has_arg,flag,val */
{"version",0,0,'v'}, /* name,has_arg,flag,val */
{0,0,0,0}
};
O último elemento da matriz deve ter valor zero em todos os componentes da estrutura option.
flag e val trabalham em conjunto. Quando você quiser que getopt_long retorne uma letra que abrevia a opção longa, use como mostrado acima, ou seja, flag com o valor de zero e val com a letra a ser retornada.
Quando quiser usar flag você deve fazer assim:
static int chave = 0; /* iniciando a flag */
static struct option opcoes_longas[]=
{
{"help",0,0,'h'},
{"version",0,&chave,1},
{0,0,0,0}
};
Neste caso, se a opção passada na linha de comando for "help" a função getopt_long retornará "h", simulando assim a passagem de uma opção curta, porém se a opção passada for "version", o valor 1 será armazenado na variável "chave"
O argumento indice_opcoes_longas é usado da seguinte maneira: um índice interno da função getopt_long inicia em zero e é usado para comparar a opção passada na linha de comando com o elemento opcoes_longas[índice].name. Se a opção passada for igual a opcoes_longas[índice].name, o índice é armazenado em indice_opcoes_longas para ser usado no processamento dos outros elementos da estrutura. Caso contrário o índice é incrementado e nova comparação é feita até o final da matriz de estruturas.
Vamos a um exemplo:
/* Processando opções da linha de comando com getopt_long() */
#include <stdio.h>
#include <getopt.h>
int main(int argc,char *argv[])
{
int opcao;
static int chave = 0;
int indice_opcoes_longas = 0;
static char opcoes[] = "hg:c";
static struct option opcoes_longas[]=
{
{"help",0,0,'h'},
{"version",0,&chave,1},
{0,0,0,0}
};
opterr = 0;
while((opcao = getopt_long(argc,argv,
opcoes,
opcoes_longas,
&indice_opcoes_longas)) != -1)
switch(opcao)
{
case 0:
break;
case 'h':
{
printf("Exibindo ajuda.\n");
break;
}
case 'g':
{
printf("opção -g escolhida.\n");
printf("esta opção recebeu o argumento %s.\n",optarg);
break;
}
case 'c':
{
printf("opção -c escolhida.\n");
break;
}
default:
printf("opção inválida!\n");
}
if(chave != 0)
printf("Versão 1.0\n");
return(0);
}
está ai ^^