PRG29003: Argumentos de linha de comando

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

Argumentos de linha de comando são dados passados para programas no momento de suas execuções. A linha de comando é formada pelo nome do arquivo de programa a ser executado, seguido de argumentos opcionais. Muitos programas de sistemas operacionais *nix (tais como Linux) exploram esses argumentos para informar o que se deseja que um programa realize. Por exemplo, o programa ls lista o conteúdo de um subdiretório de diferentes maneiras, dependendo das opções usadas em sua execução:

# faz uma listagem simples
aluno@M1:~$ ls
Argparse.cpp  Argparse.h
# opção -l ativa a listagem longa, com mais detalhes

aluno@M1:~$ ls -l
-rw-rw-r-- 1 msobral msobral 3965 Ago 23  2017 Argparse.cpp
-rw-rw-r-- 1 msobral msobral 2708 Ago 23  2017 Argparse.h
# opção -l ativa a listagem longa, com mais detalhes, e opção -a 
# mostra arquivos ocultos (iniciados com .)

aluno@M1:~$ ls -l -a
drwxrwxr-x  5 msobral msobral 4096 Mar 20 09:26 .
drwxrwxr-x 52 msobral msobral 4096 Mar 20 08:49 ..
-rw-rw-r-- 1 msobral msobral 3965 Ago 23  2017 Argparse.cpp
-rw-rw-r-- 1 msobral msobral 2708 Ago 23  2017 Argparse.h

O processamento dos argumentos de linha de comando é necessário em diferentes programas, e boa parte dele pode ser generalizada. De fato, existem bibliotecas que oferecem recursos para realizar o processamento dos argumentos:


Ambas opções acima são bastante utilizadas e completas. No entanto, por se pretenderem genéricas, apresentam alguns detalhes a serem bem compreendidos para que possam ser utilizadas (veja os manuais). Uma alternativa é esta pequena classe que processa os argumentos de forma simplificada:

A classe Argparse é capaz de processar argumentos com opções curtas e longas, com ou sem valores complementares. Algumas definições podem esclarecer isso:

  • Opção curta: informada com uma única letra e precedida por um hífen. Ex: -f
  • Opção longa: informada com duas ou mais letras e precedida por dois hífens. Ex: --tipo
  • Opção com valor complementar: a opção pede um valor. Ex: -p /home, --tipo arquivo
  • Opção sem valor complementar: nenhum valor deve ser acrescentado à opção. Ex: -b, --path.

Valores complementares de opções são sempre do tipo string. Opções sem valor complementar, chamadas de flag, possuem valor bool (true se opção aparece na linha de comando, false caso contrário).


A classe Argparse possui esta interface:

class Argparse {
public:
    Argparse();
    Argparse(const Argparse& orig);
    virtual ~Argparse();

    // Métodos para adicionar uma opção do tipo flag. Tal tipo de opção
    // não requer um valor a ser informado na linha de comando.
    // Ela é do tipo bool: se aparece na linha de comando seu valor é true,    
    // e, caso não apareça, seu valor é false.
    void add_flag(char shortoption);
    void add_flag(const string & longoption);
    
    // Métodos para adicionar uma opção do tipo flag com um valor
    // predefinido
    void add_flag(char shortoption, bool defval);
    void add_flag(const string & longoption, bool defval);
    
    
    // Métodos para adicionar uma opção comum. Tal tipo de opção
    // requer um valor a ser informado na linha de comando.
    // Ela é do tipo string: se aparece na linha de comando, a string que a sucede
    // se torna seu valor. Caso essa opção não apareça, seu valor é uma string vazia.
    void add_option(char shortoption);
    void add_option(const string & longoption);
    
    // Métodos para adicionar uma opção comum com um valor
    // predefinido    
    void add_option(char shortoption, const string & defval);
    void add_option(const string & longoption, const string & defval);
    
    // Métodos para obter o valor de uma opção comum
    string get_option(char shortoption) const;
    string get_option(const string & longoption) const;
    string operator[](const string & longoption) const;
    string operator[](char shortoption) const;

    // Métodos para obter o valor de uma opção do tipo flag
    bool get_flag(char shortoption) const ;
    bool get_flag(const string & longoption) const;
    
    // Método para obter os argumentos que não foram processados como
    // opções.
    string get_extra() const { return extra;}
    
    // Método para analisar os argumentos de linha de comando e extrair
    // as opções e seus valores contidos nesses argumentos. O vetor argv
    // corresponde ao parâmetro argv da função main. A análise das opções
    // é efetuada a partir da segunda posição do vetor (argv[1]).
    int parse(char * argv[]);
};


O programa a seguir ilustra o uso de Argparse, supondo um programa que tenhas as opções sem valor complementar -L, -P, e as opções com valor complementar -e, -p, --type.

#include <cstdlib>
#include <iostream>
#include "Argparse.h"

using namespace std;

/*
 * 
 */
int main(int argc, char** argv) {
    Argparse args;
      
    /* Demonstração do analisador de argumentos de linha de comando
     
     As opções contidas nessa demonstração são:
     
     -e EXTENSÃO 
     --type TIPO
     -p CAMINHO
     -L
     -P
     * 
     * Assim, o programa pode ser executado com qualquer combinação dessas opções,
     * as quais podem aparecer em qualquer ordem na linha de comando.
     */

    args.add_option('e');
    args.add_flag('L');
    args.add_flag('P', true);
    args.add_option('p');
    args.add_option("type", "file");
    
    int n = args.parse(argv);
    
    cout << "Identificou " << n << " opções" << endl;

    cout << "ext=" << args['e'] << endl;
    cout << "alg: largura=" << args.get_flag('L');
    cout << ", profundidade=" << args.get_flag('P') << endl;    
    cout << "path=" << args['p'] << endl;
    cout << "tipo=" << args["type"] << endl;
    cout << "extra=" << args.get_extra() << endl;
          
    return 0;
}