Wie parsen Sie Befehlszeilenargumente in C ++?

Mögliche Duplikate:
Welche Parameter-Parser-Bibliotheken gibt es für C ++?

Was ist die beste Methode zum Parsen von Befehlszeilenargumenten in C ++, wenn das Programm so ausgeführt wird:

prog [-abc] [input [output]] 

Gibt es dafür eine Bibliothek in STL?


Verbunden:

  • Befehlszeilenargumente in einer Unicode-C ++ – Anwendung analysieren

Boost.Program_options sollte den Trick machen

Die Vorschläge für boost::program_options und GNU getopt sind gut.

Für einfache Befehlszeilenoptionen verwende ich jedoch std :: find

Zum Beispiel, um den Namen einer Datei nach einem Befehlszeilenargument -f zu lesen. Sie können auch einfach feststellen, ob eine Einzelwortoption wie -h für Hilfe übergeben wurde.

 #include  char* getCmdOption(char ** begin, char ** end, const std::string & option) { char ** itr = std::find(begin, end, option); if (itr != end && ++itr != end) { return *itr; } return 0; } bool cmdOptionExists(char** begin, char** end, const std::string& option) { return std::find(begin, end, option) != end; } int main(int argc, char * argv[]) { if(cmdOptionExists(argv, argv+argc, "-h")) { // Do stuff } char * filename = getCmdOption(argv, argv + argc, "-f"); if (filename) { // Do interesting things // ... } return 0; } 

Bei dieser Vorgehensweise müssen Sie std :: strings als Wert für std :: find verwenden. Andernfalls wird die Gleichheitsprüfung für die pointerswerte durchgeführt.


Ich hoffe, es ist in Ordnung, diese Antwort zu bearbeiten und stattdessen eine neue hinzuzufügen, da dies auf der ursprünglichen Antwort basiert. Ich habe die functionen etwas neu geschrieben und sie in einer class gekapselt, also hier der Code. Ich dachte, es wäre praktisch, es auch so zu benutzen:

 class InputParser{ public: InputParser (int &argc, char **argv){ for (int i=1; i < argc; ++i) this->tokens.push_back(std::string(argv[i])); } /// @author iain const std::string& getCmdOption(const std::string &option) const{ std::vector::const_iterator itr; itr = std::find(this->tokens.begin(), this->tokens.end(), option); if (itr != this->tokens.end() && ++itr != this->tokens.end()){ return *itr; } static const std::string empty_string(""); return empty_string; } /// @author iain bool cmdOptionExists(const std::string &option) const{ return std::find(this->tokens.begin(), this->tokens.end(), option) != this->tokens.end(); } private: std::vector  tokens; }; int main(int argc, char **argv){ InputParser input(argc, argv); if(input.cmdOptionExists("-h")){ // Do stuff } const std::string &filename = input.getCmdOption("-f"); if (!filename.empty()){ // Do interesting things ... } return 0; } 

Ich kann vorschlagen, Templazed C ++ Command Line Parser Library (einige Gabeln auf GitHub sind verfügbar), die API ist sehr einfach und (zitiert von der Website):

Die Bibliothek ist vollständig in Header-Dateien implementiert, was die Verwendung und Verteilung mit anderer Software vereinfacht. Es ist lizenziert unter der MIT-Lizenz für eine sorgenfreie Verteilung.

Dies ist ein Beispiel aus dem Handbuch, das hier zur Vereinfachung dargestellt ist:

 #include  #include  #include  #include  int main(int argc, char** argv) { // Wrap everything in a try block. Do this every time, // because exceptions will be thrown for problems. try { // Define the command line object, and insert a message // that describes the program. The "Command description message" // is printed last in the help text. The second argument is the // delimiter (usually space) and the last one is the version number. // The CmdLine object parses the argv array based on the Arg objects // that it contains. TCLAP::CmdLine cmd("Command description message", ' ', "0.9"); // Define a value argument and add it to the command line. // A value arg defines a flag and a type of value that it expects, // such as "-n Bishop". TCLAP::ValueArg nameArg("n","name","Name to print",true,"homer","string"); // Add the argument nameArg to the CmdLine object. The CmdLine object // uses this Arg to parse the command line. cmd.add( nameArg ); // Define a switch and add it to the command line. // A switch arg is a boolean argument and only defines a flag that // indicates true or false. In this example the SwitchArg adds itself // to the CmdLine object as part of the constructor. This eliminates // the need to call the cmd.add() method. All args have support in // their constructors to add themselves directly to the CmdLine object. // It doesn't matter which idiom you choose, they accomplish the same thing. TCLAP::SwitchArg reverseSwitch("r","reverse","Print name backwards", cmd, false); // Parse the argv array. cmd.parse( argc, argv ); // Get the value parsed by each arg. std::string name = nameArg.getValue(); bool reverseName = reverseSwitch.getValue(); // Do what you intend. if ( reverseName ) { std::reverse(name.begin(),name.end()); std::cout < < "My name (spelled backwards) is: " << name << std::endl; } else std::cout << "My name is: " << name << std::endl; } catch (TCLAP::ArgException &e) // catch any exceptions { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; } } 

Sie können GNU GetOpt (LGPL) oder einen der verschiedenen C ++ – Ports wie getoptpp (GPL) verwenden.

Ein einfaches Beispiel mit GetOpt von dem, was Sie wollen ( prog [-ab] -Eingabe ) ist das Folgende:

 // C Libraries: #include  #include  #include  // Namespaces: using namespace std; int main(int argc, char** argv) { int opt; string input = ""; bool flagA = false; bool flagB = false; // Retrieve the (non-option) argument: if ( (argc < = 1) || (argv[argc-1] == NULL) || (argv[argc-1][0] == '-') ) { // there is NO input... cerr << "No argument provided!" << endl; //return 1; } else { // there is an input... input = argv[argc-1]; } // Debug: cout << "input = " << input << endl; // Shut GetOpt error messages down (return '?'): opterr = 0; // Retrieve the options: while ( (opt = getopt(argc, argv, "ab")) != -1 ) { // for each option... switch ( opt ) { case 'a': flagA = true; break; case 'b': flagB = true; break; case '?': // unknown option... cerr << "Unknown option: '" << char(optopt) << "'!" << endl; break; } } // Debug: cout << "flagA = " << flagA << endl; cout << "flagB = " << flagB << endl; return 0; } 

Eine weitere Alternative ist der Lean Mean C ++ Option Parser:

http://optionparser.sourceforge.net

Es ist eine Header-only-Bibliothek (nur eine einzige Header-Datei, tatsächlich) und im Gegensatz zu allen anderen Vorschlägen ist es auch freistehend, dh es hat keinerlei Abhängigkeiten. Insbesondere besteht keine Abhängigkeit von der STL. Es verwendet nicht einmal Ausnahmen oder irgendetwas anderes, das Bibliotheksunterstützung benötigt. Dies bedeutet, dass es mit einfachem C oder anderen Sprachen verknüpft werden kann, ohne “fremde” Bibliotheken einzuführen.

Wie boost :: program_options bietet seine API einen bequemen direkten Zugriff auf Optionen, dh Sie können Code wie diesen schreiben

if (Optionen [HILFE]) …;

und

int Ausführlichkeit = Optionen [VERBOSE] .count ();

Im Gegensatz zu boost :: program_options verwendet dies jedoch einfach ein Array, das mit einer (vom Benutzer bereitgestellten) Enumeration indiziert ist. Dies bietet den Komfort eines assoziativen Containers ohne das Gewicht.

Es ist gut dokumentiert und hat eine firmenfreundliche Lizenz (MIT).

TLMC ++ OP enthält einen netten Formatierer für Verwendungsbenachrichtigungen, der Zeilenumbruch und Spaltenausrichtung ausführen kann, was nützlich ist, wenn Sie Ihr Programm lokalisieren, weil es sicherstellt, dass die Ausgabe auch in Sprachen mit längeren Nachrichten gut aussieht. Es erspart Ihnen auch die lästige manuelle Formatierung Ihrer Verwendung für 80 Spalten.

 for (int i = 1; i < argc; i++) { if (strcmp(argv[i],"-i")==0) { filename = argv[i+1]; printf("filename: %s",filename); } else if (strcmp(argv[i],"-c")==0) { convergence = atoi(argv[i + 1]); printf("\nconvergence: %d",convergence); } else if (strcmp(argv[i],"-a")==0) { accuracy = atoi(argv[i + 1]); printf("\naccuracy:%d",accuracy); } else if (strcmp(argv[i],"-t")==0) { targetBitRate = atof(argv[i + 1]); printf("\ntargetBitRate:%f",targetBitRate); } else if (strcmp(argv[i],"-f")==0) { frameRate = atoi(argv[i + 1]); printf("\nframeRate:%d",frameRate); } } 

AnyOption ist eine C ++ – class zum einfachen Analysieren komplexer Befehlszeilenoptionen. Es analysiert auch Optionen aus einer Rsourcefile im Optionswertpaar-Format.

AnyOption implementiert die traditionellen POSIX-Zeichenoptionen (-n) sowie die neueren langen GNU-Optionen (–name). Oder Sie können eine einfachere lange Optionsversion (-name) verwenden, indem Sie die POSIX-Stiloptionen ignorieren.

Ich würde boost :: program_options empfehlen, wenn Sie die Boost-Lib verwenden können.

Es gibt weder in STL noch in den regulären C ++ / C-Laufzeitbibliotheken spezifische Informationen.

Versuchen Sie die CLPP-Bibliothek. Es ist eine einfache und flexible Bibliothek für das Parsen von Kommandozeilenparametern. Nur-Kopf- und plattformübergreifend Verwendet nur ISO C ++ – und Boost C ++ – Bibliotheken. IMHO ist es einfacher als Boost.Program_options.

Bibliothek: http://sourceforge.net/projects/clp-parser

26. Oktober 2010 – neues Release 2.0rc. Viele behobene Fehler, vollständiges Refactoring des Quellcodes, Dokumentation, Beispiele und Kommentare wurden korrigiert.

Ziemlich späte Antwort, aber ich habe GetPot für einige Projekte verwendet: http://getpot.sourceforge.net/

Hauptmerkmal: Alles ist in einer einzigen Header-Datei, keine Build-Probleme. Speichern Sie es einfach irgendwo auf Ihrem Rechner und “#include” es in Ihre Datei mit main()

Wurde in letzter Zeit nicht aktualisiert, aber gut dokumentiert und funktioniert gut. Du kannst es versuchen.