noname: / C++: commandline parsing

Hallo SelfForum.

Ich möchte eine Kommandozeile parsen (C++). Optionen können sowohl in Kurz- oder Langform (--help, -h) und mit oder ohne Argument(en) in "unbegrenzter" Anzahl und nicht definierter Reihenfolge vorkommen.

Welchen Ansatz haltet ihr hier für effizient und würdet ihr verfolgen? Ich würde mich über ein paar Anregungen und Vorschläge freuen.

Mein (unreifer?) Ansatz:
Ich nehme Structs zu Hilfe; etwa:

Struct 1: Hier stecke ich alle möglichen Optionen rein, zusammen mit Metainfos wie hat-Argument oder nicht und Typ-des-Argument. Z.B.:

  
struct options {  
   string option_long;  
   string option_short;  
   bool has_argument;  
   string type_of_argument;  
};  
  
struct options * cmdopts;  

Struct 2: Hier lege ich alle Optionen und Argumente von der Kommandozeile zur späteren Abarbeitung ab, sofern sie valide waren. Z.B.:

  
struct cmdline {  
   string option;  
   bool has_argument;  
   string argument; /* oder vector<string>; je nach Bedarf */  
};  
  
struct cmdline * cmdargs;  

getopt und getopt_long, da unixspezifisch, möchte ich nach Möglichkeit nicht verwenden (Oder existiert hier ein vergleichbares Pendant in der WinWelt?) bzw. mir ist es wichtig, den Parser selbst zu implementieren.

Anmerkung: Mir ist es bewusst, dass es einen Haufen an Libraries gibt, etwa boost::program_options oder anyoption. Auch wenn Boost quasi-Standard ist, wäre das in meinem Fall eher Overkill.

Dank und beste Grüße.

  1. hi,

    Ich möchte eine Kommandozeile parsen (C++). Optionen können sowohl in Kurz- oder Langform (--help, -h) und mit oder ohne Argument(en) in "unbegrenzter" Anzahl und nicht definierter Reihenfolge vorkommen.

    Welchen Ansatz haltet ihr hier für effizient und würdet ihr verfolgen? Ich würde mich über ein paar Anregungen und Vorschläge freuen.

    getopt(). Schaus Dir mal an, das ist eine c-Funktion.

    Hotte

    --
    Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
    1. Hallo.

      getopt und getopt_long, da unixspezifisch, möchte ich nach Möglichkeit nicht verwenden (Oder existiert hier ein vergleichbares Pendant in der WinWelt?)

      getopt(). Schaus Dir mal an, das ist eine c-Funktion.

      Weitere Vorschläge?

      1. Hi,

        getopt und getopt_long, da unixspezifisch, möchte ich nach Möglichkeit nicht verwenden (Oder existiert hier ein vergleichbares Pendant in der WinWelt?)
        Weitere Vorschläge?

        boost::program_options
        http://www.boost.org/doc/libs/1_37_0/doc/html/program_options.html

        Läuft auf den meisten Betriebsystemen/Compilern und ist ziemlich bequem.

        Generell ist boost eine gute Stelle um mal schnell nachzuschauen.

        Grüße,
        Andres Freund

        1. Hallo Andres,

          die Boost Lib. kenne ich (siehe OP). Weitere Vorschläge?

          1. Moin Moin!

            Weitere Vorschläge?

            Benutze eine Suchmaschine, entweder generisch oder auf Software spezialisiert, lade Bibliotheken herunter, die Deinen Anforderungen entsprechen könnten, und teste sie SELBST.

            Fang mit getopt_long an.

            Alexander

            --
            Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
  2. Hallo,

    Anmerkung: Mir ist es bewusst, dass es einen Haufen an Libraries gibt, etwa boost::program_options oder anyoption. Auch wenn Boost quasi-Standard ist, wäre das in meinem Fall eher Overkill.

    Naja, C-basiert gibt's noch POPT als Library, das funktioniert anscheinend auch unter Windows (das aber nie getestet), allerdings glaube ich nicht, dass Du hier jemanden finden wirst, der Dir hilft, Deine eigene Lib zu schreiben, nur, weil Du keine Lust hast, etwas vorgefertigtes zu nehmen. Es gibt da einfach zu viele Möglichkeiten, vorhandenen Code zu nutzen, als dass sich die wenigen Leute hier im Forum, die sich mit C auskennen, jemals Gedanken gemacht hätten, sowas selbst zu bauen.

    Naja, ansonsten zum Thema Datenstrukturdesign, da Du offensichtlich C++ verwendest, würde ich in etwa folgendes machen (schnell zusammengehackt, kann man sicher besser machen):

    struct option {  
      char short;  // 0, wenn keine kurze option verfügbar  
      string long; // leer, wenn keine lange option verfügbar  
      int takesarg; // ob man zu dieser option ein argument mitgeben muss  
      int optional; // ob die option angegeben werden muss  
    };  
      
    struct parsed_option {  
      char short;  // kopiert aus der jew. struct option  
      string long; // kopiert aus der jew. struct option  
      int hadarg;  // ob die option ein argument hatte  
      string arg;  // der inhalt des arguments  
    };  
      
    class OptionParser {  
      // Wie private/protected aussieht sei Dir überlassen  
      public:  
        // Konstruktor: Initialisiere den Option-Parser  
        // (kannst gerne auch was anderes als vector nehmen)  
        OptionParser (vector<option> options);  
        // Parse Argumente, gibt an ob alles korrekt war  
        bool parse (int argc, char **argv);  
        // Gib die angegebenen optionen zurück  
        vector <parsed_option> getOptions ();  
        // Gib die verbleibenden Argumente zurück  
        vector <string> getArguments ();  
    }
    

    Kann man wie gesagt sicher noch stark verbessern oder beliebig verkomplizieren. Ich verstehe aber nicht, warum Du Dich nicht auf bereits geschriebenen, gut getesteten Code verlassen willst und stattdessen so etwas nachprogrammieren willst...

    Viele Grüße,
    Christian