如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:

prog [-abc] [input [output]]

是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?


相关:

在unicode c++应用程序中解析命令行参数


当前回答

尝试CLPP库。它是用于命令行参数解析的简单而灵活的库。仅头部和跨平台。仅使用ISO c++和Boost c++库。恕我直言,这比Boost.Program_options简单。

图书馆:http://sourceforge.net/projects/clp-parser

2010年10月26日-新发布2.0rc。修正了许多bug,完整的源代码重构、文档、示例和注释都得到了修正。

其他回答

如果这是linux/unix,那么使用的标准是gnu getopt

http://www.gnu.org/s/libc/manual/html_node/Getopt.html

它太大了,不可能包含在Stack Overflow回答中,但我创建了一个用于声明式定义命令行的库。它利用了c++ 14通过给每个成员变量赋初始值来构建类构造函数的能力。

这个库基本上是一个基类。要定义命令语法,需要声明一个派生自该语法的结构。下面是一个例子:

struct MyCommandLine : public core::CommandLine {
    Argument<std::string> m_verb{this, "program", "program.exe",
        "this is what my program does"};
    Option<bool> m_help{this, "help", false,
        "displays information about the command line"};
    Alias<bool> alias_help{this, '?', &m_help};
    Option<bool> m_demo{this, "demo", false,
        "runs my program in demonstration mode"};
    Option<bool> m_maximize{this, "maximize", false,
        "opens the main window maximized"};
    Option<int> m_loops{this, "loops", 1,
        "specifies the number of times to repeat"};
    EnumOption<int> m_size{this, "size", 3,
                           { {"s", 1},
                             {"small", 1},
                             {"m", 3},
                             {"med", 3},
                             {"medium", 3},
                             {"l", 5},
                             {"large", 5} } };
    BeginOptionalArguments here{this};
    Argument<std::string> m_file{this, "file-name", "",
        "name of an existing file to open"};
} cl;

参数、选项和别名类模板是在CommandLine基类的范围内声明的,您可以为自己的类型专门化它们。每个选项都包含this指针、选项名称、默认值和用于打印命令概要/用法的描述。

我仍然在寻找消除所有这些指针的需要,但我还没有找到一种不引入宏的方法。这些指针允许每个成员向驱动解析的基类中的表注册自己。

一旦有了实例,就会有多个方法重载来解析来自字符串或主样式参数向量的输入。解析器同时处理windows风格和unix风格的选项语法。

if (!cl.Parse(argc, argv)) {
    std::string message;
    for (const auto &error : cl.GetErrors()) {
        message += error + "\n";
    }
    std::cerr << message;
    exit(EXIT_FAILURE);
}

一旦它被解析,你可以使用operator()访问任何选项的值:

if (cl.m_help()) { std::cout << cl.GetUsage(); }
for (int i = 0; i < cl.m_loops(); ++i) { ... }

整个库只有大约300行(不包括测试)。实例有点臃肿,因为解析表是实例(而不是类)的一部分。但是每个程序通常只需要一个实例,而且这种纯声明性方法的便利性非常强大,可以通过解析新输入简单地重置实例。

AnyOption是一个c++类,用于轻松解析复杂的命令行选项。它还以选项值对格式解析来自rsourcefile的选项。

AnyOption实现了传统的POSIX风格的字符选项(-n)以及较新的GNU风格的长选项(——name)。或者您可以通过要求忽略POSIX样式选项来使用更简单的长选项版本(-name)。

提高program_options。

Qt 5.2提供了一个命令行解析器API。

小例子:

#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>

int main(int argc, char **argv)
{
  QCoreApplication app(argc, argv);
  app.setApplicationName("ToolX");
  app.setApplicationVersion("1.2");

  QCommandLineParser parser;
  parser.setApplicationDescription("Tool for doing X.");
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("infile",
      QCoreApplication::translate("main", "Input file."));

  QCommandLineOption verbose_opt("+",
      QCoreApplication::translate("main", "be verbose"));
  parser.addOption(verbose_opt);

  QCommandLineOption out_opt(QStringList() << "o" << "output",
      QCoreApplication::translate("main", "Output file."),
      QCoreApplication::translate("main", "filename"), // value name
      QCoreApplication::translate("main", "out")   // default value
      );
  parser.addOption(out_opt);

  // exits on error
  parser.process(app);

  const QStringList args = parser.positionalArguments();

  qDebug() << "Input files: " << args
    << ", verbose: " << parser.isSet(verbose_opt)
    << ", output: " << parser.value(out_opt)
    << '\n';
  return 0;
}

示例输出

自动生成的帮助界面:

$ ./qtopt -h
Usage: ./qtopt [options] infile
Tool for doing X.

Options:
  -h, --help               Displays this help.
  -v, --version            Displays version information.
  -+                       be verbose
  -o, --output   Output file.

Arguments:
  infile                   Input file.

自动生成版本输出:

$ ./qtopt -v
ToolX 1.2

一些真实的电话:

$ ./qtopt b1 -+ -o tmp blah.foo
Input files:  ("b1", "blah.foo") , verbose:  true , output:  "tmp"
$ ./qtopt          
Input files:  () , verbose:  false , output:  "out"

解析错误:

$ ./qtopt --hlp
Unknown option 'hlp'.
$ echo $?
1

结论

如果您的程序已经使用了Qt(>= 5.2)库,那么它的命令行解析API足以方便地完成工作。

请注意,内置Qt选项在选项解析器运行之前会被QApplication使用。