Comunidade OSDevBrasil.net
Maio 20, 2012, 04:23:21 *
Bem-vindo, Visitante. Por favor faça o Login ou Registro.

Login com nome de usuário, senha e duração da sessão
Notícias: Anuncie a nossa comunidade a amigos, fóruns...
 
   Home   Ajuda Pesquisa Login Registrar  
Páginas: [1]
  Imprimir  
Autor Tópico: Trabalhando com opções de linha de comando  (Lida 1390 vezes)
Bencz
OS Full Member
***

Karma: 0
Mensagens: 112



Ver Perfil
« : Junho 07, 2009, 02:42:06 »

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:
Citar
/* 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:
Citar
/* 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 ^^

Registrado



Mounter
Administrador
OS Sr. Member
*****

Karma: 12
Mensagens: 432


mrjostz@hotmail.com
Ver Perfil WWW Email
« Responder #1 : Novembro 06, 2009, 09:38:54 »

Bem interessante mesmo, vou ver se implemento essa função na lib c do SOmBRA.
Registrado

╔╗╔╦══╦╗╔╦══╦╗
║╚╝║╔╗║╚╝║╔╗║║
║╔╗║╠╣║╔╗║╠╣╠╣
╚╝╚╩╝╚╩╝╚╩╝╚╩╝

Projeto SOmBRA - http://code.google.com/p/projeto-sombra

S.O.: Ubuntu 10.04
Browser: Google Chrome 10

Bencz
OS Full Member
***

Karma: 0
Mensagens: 112



Ver Perfil
« Responder #2 : Novembro 06, 2009, 09:47:59 »

Bem interessante mesmo, vou ver se implemento essa função na lib c do SOmBRA.

dai sim em, compila os codigos ja no sombra e testa ali rapidamente  Sorridente
Registrado



Páginas: [1]
  Imprimir  
 
Ir para:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2006-2009, Simple Machines XHTML 1.0 Válido! CSS Válido!