Qual è il modello di progettazione per l'elaborazione di argomenti della riga di comando
-
09-06-2019 - |
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)
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.
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.
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.