Frage

Wenn Sie ein Programm schreiben, das über die Befehlszeile ausführbar ist, möchten Sie dem Benutzer häufig mehrere Optionen oder Flags anbieten, zusammen mit möglicherweise mehr als einem Argument.Ich bin schon oft darüber gestolpert, aber gibt es eine Art Entwurfsmuster zum Durchlaufen von Argumenten und zum Aufrufen der entsprechenden Handlerfunktionen?

Halten:

myprogram -f filename -d directory -r regex

Wie organisieren Sie die Handlerfunktionen, nachdem Sie die Argumente mithilfe der für Ihre Sprache integrierten Funktionen abgerufen haben?(Sprachspezifische Antworten sind willkommen, wenn Ihnen das dabei hilft, eine Antwort zu formulieren.)

War es hilfreich?

Lösung

Ich weiß nicht, von irgendwelchen dokumentiert „Muster“ für die Verarbeitung.

Ich glaube, eine der ältesten Bibliotheken / APIs für den Umgang mit Argumenten ist getopt. „Getopt“ zeigt viele Menschen Seiten und Links zu Implementierungen googeln.

Im Allgemeinen Ich habe einen Vorliebe oder Einstellungen Dienst in meiner Anwendung, die das Argument Prozessor weiß, wie mit zu kommunizieren. Argumente werden dann in etwas in diesem Dienst übersetzt, dass die Anwendung als dann abfragen. Dies könnte so einfach wie ein Wörterbuch von Einstellungen (wie eine String Einstellung mit dem Namen „Dateiname“).

Andere Tipps

Ich denke, die folgende Antwort mehr entlang der Linien ist von dem, was Sie suchen:

Sie suchen sollen die Vorlage Muster (Template-Methode in "Design Patterns" [Gamma, el al])

bei der Anwendung

Kurz gesagt, es ist insgesamt Verarbeitung sieht wie folgt aus:

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

Kurz gesagt, eine ConsoleEngineBase Klasse implementieren, die Methoden zur hat:

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

Dann ein Chassis erstellen, die eine ConsoleEngine () Instanz instanziiert und sendet die Main () Nachricht es zu beginnen.

Um ein gutes Beispiel dafür, wie dies auf den folgenden Link überprüfen zu einer Konsole oder Kommandozeilen-Programm anzuwenden: http://msdn.microsoft.com/en-us/magazine/cc164014.aspx

Das Beispiel ist in C #, aber die Ideen sind in einer anderen Umgebung leicht umgesetzt werden.

Sie am getopt () als nur den Teil aussehen würden, die die in das Argument passen Handling (Pre-Processing).

Hope, das hilft.

Sie haben die Sprache nicht erwähnen, aber für Java haben wir Apache Commons CLI geliebt. Für C / C ++, getopt.

Ein paar Anmerkungen zu diesem ...

Erstens, während es keine Muster per se ist, einen Parser zu schreiben ist im Wesentlichen eine mechanische Bewegung, gegeben, da eine Grammatik, kann ein Parser leicht erzeugt werden. Tools wie Bison und ANTLR in den Sinn kommen.

Das heißt, Parser-Generatoren sind in der Regel viel des Guten für die Kommandozeile. Also das übliche Muster ist selbst eine Beurteilung zu schreiben (wie andere haben gezeigt) ein paar Mal, bis Sie krank werden mit dem langweiligen Detail des Umgangs und eine Bibliothek finden, um es für Sie zu tun.

ich eine für C ++ geschrieben, die eine Reihe von Aufwand spart, die imparts getopt und macht schöne Verwendung von Vorlagen: TCLAP

Nun, es ist eine alte Post, aber ich würde immer noch beitragen möge. Die Frage wurde auf Wahl von Entwurfsmustern bestimmt aber ich auf viele Diskussionen sehen könnte, die Bibliothek zu nutzen. Ich habe Microsoft Link per lindsay ausgecheckt, die über Template-Design-Muster spricht zu verwenden.

Allerdings bin ich mit der Post nicht überzeugt. Schablonenmuster Absicht ist es, eine Vorlage zu definieren, die von verschiedenen anderen Klassen implementiert werden einheitliches Verhalten haben. Ich glaube nicht, Kommandozeilen-Parsing richtig passt.

Ich würde lieber mit „Command“ Entwurfsmuster gehen. Dieses Muster ist beste Lösung für menügesteuert Optionen.

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

so in Ihrem Fall, -f -d und -r alle Befehle, die wird definiert gemeinsamen oder getrennten Empfänger. Auf diese Weise mehr Empfänger können in Zukunft definiert werden. Der nächste Schritt wird diese Verantwortung von Befehlen, falls es einer Verarbeitungskette erforderlich, um Kette sein. Für die ich wählen.

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

Ich denke, die Kombination dieser beide ist am besten, den Code für die Kommandozeilen-Verarbeitung oder einen menügesteuerten Ansatz zu organisieren.

Die boost :: program_options Bibliothek schön, wenn man in C ++ sind und haben den Luxus-Boost verwenden.

Angenommen, Sie eine „config“ Objekt, das Sie einrichten wollen mit den Flaggen und einem geeigneten Befehlszeile Parser, der die Befehlszeile Parsen und liefern einen konstanten Strom der Optionen kümmert, geht hier um einen Block von Pseudo-Code

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

Ich ziehe es Optionen wie "-t Text" und "-i 44"; Ich mag es nicht "-fname" oder "--Sehr-long-Argument = some_value".

Und? "-"., "H" und "/ h" alle produzieren eine Online-Hilfe

Hier ist, wie mein Code aussieht:

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

Ich bin Riffing auf der ANTLR Antwort von mes5k. Diese Link auf Codeproject für einen Artikel, die ANLTR und mit dem Besuch Muster diskutiert die Aktionen zu implementieren, Sie App nehmen wollen. Es ist gut geschrieben und es lohnt sich zu überprüfen.

Ich würde empfehlen, eine Befehlszeilenprozessor-Bibliothek. einigen russischen Kerl einen anständigen erstellt, aber es gibt jede Menge sie gibt. Wollen Sie etwas Zeit sparen, so dass Sie nicht über den Zweck Ihrer Anwendung konzentrieren können als Befehlszeilenschalter Parsen!

Getopt ist der einzige Weg zu gehen.

http://sourceforge.net/projects/csharpoptparse

Sie erwähnen nicht die Sprache für diese, aber wenn Sie für einen wirklich schönen Objective-C-Wrapper um getopt suchen, dann DDCLI Rahmen Dave Dribin ist wirklich schön.

http://www.dribin.org/dave / Blog / Archiv / 2008/04/29 / ddcli

Ich verwende die getopts :: std und getopts :: long in perl und auch die Getopt Funktion in C. Diese standardisiert die Analyse und das Format der Parameter. Andere Sprachen haben unterschiedliche Mechanismen für diese Handhabung.

Hope, das hilft

Die Standardausführung folgt in der Regel, was getopt der Fall ist, gibt es getopt Bibliotheken für viele Sprachen, .NET, Python, C, Perl, PHP, etc.

Das grundlegende Design ist einen Kommandozeilen-Parser zu haben, den Teil der Argumente Teil zurück bestehen in einer Schleife überprüft werden.

Diese Artikel beschreibt es in einige weitere Details.

Ich bin nicht so sehr interessiert in den Bibliotheken, obwohl das auf jeden Fall hilfreich ist. Ich war mehr für einig „Pseudo-Code“ suchen, um die Verarbeitung von sagen, dass Ihr durchschnittliches Bündel von Fahnen und ein paar mehr Argumente als Beispiel veranschaulicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top