Domanda

Se si sta scrivendo un programma eseguibile da riga di comando, è spesso necessario per offrire all'utente diverse opzioni o bandiere, insieme, probabilmente, più di un argomento.Sono incappata anch'io la mia strada attraverso questo molte volte, ma c'è una sorta di modello di progettazione per l'elaborazione ciclica di argomenti e di chiamare il gestore appropriato funzioni?

Prendere in considerazione:

myprogram -f filename -d directory -r regex

Come organizzare le funzioni del gestore dopo aver recuperato gli argomenti utilizzando qualsiasi built-ins per la vostra lingua?(specifico per la lingua risposte accolto, se aiuta ad articolare una risposta)

È stato utile?

Soluzione

Non so documentate "modelli" per l'elaborazione.

Credo che una delle più antiche librerie e Api per la gestione di argomenti è getopt.Googling "getopt" mostra un sacco di pagine man e i collegamenti per le implementazioni.

In generale, ho delle preferenze o le impostazioni di servizio, nella mia applicazione che l'argomento del processore sa come comunicare.Gli argomenti vengono poi tradotti in qualcosa in questo servizio che l'applicazione di query.Questo potrebbe essere semplice come un dizionario delle impostazioni (come una stringa di impostazione denominata "nomefile").

Altri suggerimenti

Penso che la risposta è più lungo le linee di ciò che si sta cercando:

Si dovrebbe cercare di applicare il modello di Modello (Modello di Metodo, in "Design Patterns" [Gamma, el al])

In breve è di elaborazione complessiva simile a questo:

If the arguments to the program are valid then
    Do necessary pre-processing
    For every line in the input
        Do necessary input processing
    Do necessary post-processing
Otherwise
    Show the user a friendly usage message

In breve, è necessario implementare un ConsoleEngineBase classe che dispone di metodi per:

PreProcess()
ProcessLine()
PostProcess()
Usage()
Main()

Quindi creare un telaio, che crea un'istanza di un ConsoleEngine() dell'istanza e invia il Main() messaggio di kick off.

Per vedere un buon esempio di come applicare questo per una console o un programma a riga di comando di consultare i seguenti link:http://msdn.microsoft.com/en-us/magazine/cc164014.aspx

L'esempio è in C#, ma le idee sono facilmente implementato in qualsiasi altro ambiente.

Si dovrebbe guardare il GetOpt (), come la parte che si adattano in argomento gestione (pre-processing).

Spero che questo aiuta.

Lei non ha menzionato la lingua, ma per Java abbiamo amato Apache Commons CLI.Per C/C++, getopt.

Un paio di commenti su questo...

In primo luogo, mentre non ci sono tutti i modelli di per sé, di scrivere un parser è essenzialmente un esercizio meccanico, perché, data una grammatica, un parser può essere facilmente generato.Strumenti come il Bisonte, e ANTLR vengono in mente.

Detto questo, generatori di parser sono di solito eccessivo per la riga di comando.Così il modello di consueto è quello di scrivere uno voi stessi (come altri hanno dimostrato) un paio di volte fino a che ci si ammala di trattare con il noioso dettaglio e trovare una raccolta di farlo per voi.

Ho scritto uno per C++ che consente di risparmiare un sacco di sforzo che getopt comunica e rende piacevole l'uso di modelli: TCLAP

Bene, è un vecchio post, ma vorrei comunque contribuire.La domanda era inteso nella scelta di modelli di progettazione, tuttavia, ho potuto vedere un sacco di dibattito su quale libreria utilizzare.Ho controllato link di microsoft come per lindsay che parla di modello di modello di progettazione per l'uso.

Tuttavia, io non sono convinto che con il post.Modello di modello, l'intento è quello di definire un modello che sarà attuato da varie altre classi per avere un comportamento uniforme.Non credo che l'analisi di riga di comando si inserisce in esso.

Avrei preferito andare con il "Comando" di un modello di progettazione.Questo modello è più adatta per l'guidato da menu opzioni.

http://www.blackwasp.co.uk/Command.aspx

quindi nel tuo caso, -f, -d e -r tutto diventa comandi che è comune o ricevitore separato definito.In questo modo più ricevitori possono essere definiti in futuro.Il passo successivo sarà la catena di queste responsabilità dei comandi, nel caso di una catena di trattamento richiesto.Per cui io sceglierei.

http://www.blackwasp.co.uk/ChainOfResponsibility.aspx

Credo che la combinazione di questi due sono i migliori per organizzare il codice per la riga di comando di elaborazione o di eventuali menu guidato approccio.

Il boost::program_options la biblioteca è bello se sei in C++ e hanno il lusso di utilizzare il Boost.

Supponendo di avere un "config" oggetto che è lo scopo per il programma di installazione con il flag e adatto a linea di comando parser che si occupa di analisi la riga di comando e l'alimentazione di un flusso costante di opzioni, qui va un blocco di pseudocodice

while (current_argument = cli_parser_next()) {
    switch(current_argument) {
        case "f": //Parser strips the dashes
        case "force":
            config->force = true;
            break;
        case "d":
        case "delete":
            config->delete = true;
            break;
        //So on and so forth
        default:
            printUsage();
            exit;
    }
}

Io preferisco le opzioni "-t di testo" e "-i 44";Non mi piace "-fname" o "- molto-lunghi-argomento=some_value".

E "-?", "-h" e "/h" tutti producono una schermata di aiuto.

Ecco com'è il mio codice è:

int main (int argc, char *argv[])
   {  int i;
      char *Arg;
      int ParamX, ParamY;
      char *Text, *Primary;

   // Initialize...
   ParamX = 1;
   ParamY = 0;
   Text = NULL;
   Primary = NULL;

   // For each argument...
   for (i = 0; i < argc; i++)
      {
      // Get the next argument and see what it is
      Arg = argv[i];
      switch (Arg[0])
         {
         case '-':
         case '/':
            // It's an argument; which one?
            switch (Arg[1])
               {
               case '?':
               case 'h':
               case 'H':
                  // A cry for help
                  printf ("Usage:  whatever...\n\n");
                  return (0);
                  break;

               case 't':
               case 'T':
                  // Param T requires a value; is it there?
                  i++;
                  if (i >= argc)
                     {
                     printf ("Error:  missing value after '%s'.\n\n", Arg);
                     return (1);
                     }

                  // Just remember this
                  Text = Arg;

                  break;

               case 'x':
               case 'X':
                  // Param X requires a value; is it there?
                  i++;
                  if (i >= argc)
                     {
                     printf ("Error:  missing value after '%s'.\n\n", Arg);
                     return (1);
                     }

                  // The value is there; get it and convert it to an int (1..10)
                  Arg = argv[i];
                  ParamX = atoi (Arg);
                  if ((ParamX == 0) || (ParamX > 10))
                     {
                     printf ("Error:  invalid value for '%s'; must be between 1 and 10.\n\n", Arg);
                     return (1);
                     }

                  break;

               case 'y':
               case 'Y':
                  // Param Y doesn't expect a value after it
                  ParamY = 1;
                  break;

               default:
                  // Unexpected argument
                  printf ("Error:  unexpected parameter '%s'; type 'command -?' for help.\n\n", Arg);
                  return (1);
                  break;
               }

            break;

         default:
            // It's not a switch that begins with '-' or '/', so it's the primary option
            Primary = Arg;

            break;
         }
      }

   // Done
   return (0);
   }

Sto riffing sul ANTLR risposta da mes5k.Questo link al Codeproject è un articolo che discute ANLTR e utilizzando la visita modello da implementare le azioni che si desidera che l'app per prendere.E ' ben scritto e vale la pena rivedere.

Mi consiglia di utilizzare una riga di comando processore biblioteca. Un po ' di russo ragazzo creata una decente, ma ci sono un sacco di loro là fuori.Vi farà risparmiare tempo in modo da poter concentrare lo scopo dell'app, piuttosto che l'analisi di opzioni della riga di comando!

Getopt è l'unico modo per andare.

http://sourceforge.net/projects/csharpoptparse

Come circa l'interprete del modello?http://www.dofactory.com/net/interpreter-design-pattern

Non parlare di una lingua per questo, ma se siete alla ricerca di una davvero bella Objective-C wrapper getopt poi Dave Dribin del DDCLI quadro è davvero bello.

http://www.dribin.org/dave/blog/archives/2008/04/29/ddcli

Io uso il Getopts::std e Getopts::lungo in perl e anche il Getopt funzione in C.Questo standardizza l'analisi e il formato dei parametri.Altre lingue sono diversi meccanismi per la gestione di questi.

Spero che questo aiuta

Il design standard, di solito, segue quello che getopt fa, ci sono getopt librerie per molte lingue .NET, python, C, Perl, PHP, etc.

Il disegno di base è quello di avere una riga di comando parser che restituisce parte da parte gli argomenti passati al check-in di un ciclo.

Questo articolo discute in qualche dettaglio in più.

Io non sono tanto interessati alle librerie, anche se è sicuramente utile.Ero alla ricerca di più per alcuni "pseudo-codice", che illustra l'elaborazione di dire la tua media mazzo di bandiere e un sacco di più argomenti, come un esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top