Question

Si vous écrivez un programme exécutable à partir de la ligne de commande, vous souhaitez souvent de proposer à l'utilisateur plusieurs options ou options, ainsi que, éventuellement, plus d'un argument.J'ai tombé mon chemin à travers de nombreuses fois, mais est-il une sorte de modèle de conception pour une boucle dans args et en appelant le gestionnaire approprié fonctions?

Considérer:

myprogram -f filename -d directory -r regex

Comment vous organisez-vous les fonctions de gestionnaire d'après vous récupérer les arguments à l'aide de quelque built-ins pour votre langue?(spécifique à la langue des réponses accueilli, si cela vous aide à formuler une réponse)

Était-ce utile?

La solution

Je ne sais pas du tout documenté "modèles" pour le traitement.

Je crois que l'une des plus anciennes bibliothèques/Api pour le traitement des arguments est getopt.Googler "getopt" montre beaucoup de l'homme des pages et des liens à des implémentations.

En général, j'ai une préférences ou les paramètres de service dans mon application que l'argument processeur sait comment communiquer avec.Les Arguments sont alors transformés en quelque chose dans ce service que l'application de requête.Cela pourrait être aussi simple que d'un dictionnaire de paramètres (comme une chaîne de paramètre nommé "nom de fichier").

Autres conseils

Je pense que la réponse suivante est plus le long des lignes de ce que vous cherchez:

Vous devriez chercher à appliquer le Pattern Template (Modèle de Méthode dans les "Design Patterns" [Gamma, el al])

Bref, c'est la transformation globale ressemble à ceci:

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

En bref, de mettre en œuvre un ConsoleEngineBase classe qui a des méthodes pour:

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

Puis de créer un châssis, qui instancie un ConsoleEngine() de l'instance et envoie le Main() message pour le coup d'envoi.

Pour voir un bon exemple de la façon de l'appliquer à une console ou d'un programme en ligne de commande consultez le lien suivant:http://msdn.microsoft.com/en-us/magazine/cc164014.aspx

L'exemple est en C#, mais les idées sont facilement mis en œuvre dans tout autre environnement.

Vous regardez le GetOpt() as juste la partie qui fit dans l'argument de la manipulation (pré-traitement).

Espérons que cette aide.

Vous n'avez pas parler de la langue, mais pour Java, nous avons adoré Apache Commons CLI.Pour le C/C++, getopt.

Quelques commentaires sur ce...

Tout d'abord, il n'y a aucun modèle en soi, d'écrire un analyseur syntaxique est essentiellement un exercice mécanique, donné à une grammaire, un analyseur peut être facilement généré.Des outils comme le Bison, et ANTLR viennent à l'esprit.

Cela dit, analyseur de générateurs sont généralement les excès de la ligne de commande.Ainsi, le schéma habituel est à l'écrire vous-même (comme d'autres l'ont démontré) à quelques reprises jusqu'à ce que vous tombez malade de traiter avec le détail fastidieux et trouver une bibliothèque pour le faire pour vous.

J'ai écrit un pour C++ qui permet d'économiser un tas d'effort que getopt donne et rend agréable l'utilisation de modèles: TCLAP

Eh bien, c'est un vieux post, mais je voudrais tout de même contribuer.La question a été prévu sur le choix de modèles de conception cependant j'ai pu voir beaucoup de discussion sur la bibliothèque à utiliser.J'ai vérifié les liens de microsoft comme par lindsay, qui parle de modèle de modèle de conception à utiliser.

Cependant, je ne suis pas convaincu par la poste.Modèle de modèle a pour objet de définir un modèle qui sera mis en œuvre par divers autres classes pour avoir uniforme comportement.Je ne pense pas que l'analyse de la ligne de commande s'inscrit dans il.

Je préfère aller avec "Commande" modèle de conception.Ce modèle est le meilleur ajustement pour un menu d'options.

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

donc dans votre cas, -f, -d et -r tout devient commandes communes ou séparées récepteur défini.De cette façon, plusieurs récepteurs peuvent être définies à l'avenir.La prochaine étape sera à la chaîne des responsabilités des commandes, dans le cas d'une chaîne de traitement requis.Pour qui je choisirais.

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

Je suppose que la combinaison de ces deux sont les meilleurs pour organiser le code en ligne de commande de traitement ou de n'importe quel menu driven approche.

L' boost::program_options la bibliothèque est bien si vous êtes en C++ et le luxe de l'utilisation de Boost.

En supposant que vous avez une "config" de l'objet que vous visez à l'installation avec les drapeaux et une ligne de commande de l'analyseur qui prend soin de l'analyse de la ligne de commande, et de fournir un flux constant d'options, voici un bloc de pseudocode

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;
    }
}

Je préfère, comme les options "-t texte" et "-j'ai 44";Je n'aime pas "-fname" ou "--très-long-argument=some_value".

Et "-?", "-h" et "/h" tous les produits d'un écran d'aide.

Voici comment mon code ressemble:

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);
   }

Je suis aussi sur le ANTLR réponse par mes5k.Cette lien vers Codeproject est pour un article qui traite de ANLTR et en utilisant le pattern de visite pour mettre en œuvre les actions que vous voulez vous application pour prendre.Il est bien écrit et intéressant de passer en revue.

Je vous conseille d'utiliser une ligne de commande du processeur de la bibliothèque. Un peu de russe gars créé une décente, mais il y a des tonnes d'entre eux.Va vous faire économiser du temps, de sorte que vous pouvez vous concentrer sur l'objet de votre application plutôt que de l'analyse commutateurs de ligne de commande!

Getopt est la seule façon d'aller.

http://sourceforge.net/projects/csharpoptparse

Comment au sujet de l'interprète modèle?http://www.dofactory.com/net/interpreter-design-pattern

Vous ne mentionnez pas une langue, mais si vous êtes à la recherche pour un de vraiment sympa Objective-C wrapper autour de getopt puis Dave Musée du DDCLI cadre est vraiment sympa.

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

J'utilise le Getopts::std et Getopts::long en perl et aussi le Getopt fonction en C.Cette uniformise l'analyse et le format des paramètres.D'autres langues ont différents mécanismes de la manipulation de ces.

Espérons que cette aide

La norme de conception suit généralement ce getopt, il y en a getopt des bibliothèques pour de nombreuses langues .NET, python, C, Perl, PHP, etc.

La conception de base est d'avoir une ligne de commande de l'analyseur qui renvoie en partie les arguments passés à vérifier dans une boucle.

Cette l'article en parle un peu plus en détail.

Je ne suis pas intéresse aussi bien dans les bibliothèques, si c'est vraiment utile.J'ai été à la recherche pour certains "pseudo-code" qui illustre la transformation de dire la moyenne de votre tas de drapeaux et d'un tas de plus d'arguments, comme un exemple.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top