• Qt:解析命令行


    Qt从5.2版開始提供了两个类QCommandLineOption和QCommandLineParser来解析应用的命令行參数。


    一、命令行写法
    命令行:"-abc"

    在QCommandLineParser的解析模式为ParseAsCompactedShortOptions(默认)时会被觉得是3个參数,即"-a"、"-b"和"-c"

    QCommandLineOption op1("a");
    QCommandLineOption op2("b");
    QCommandLineOption op3("c");
    
    QCommandLineParser parser;
    parser.addOption(op1);
    parser.addOption(op2);
    parser.addOption(op3);
    parser.process(a);
    
    qDebug() << parser.isSet(op1);  // true
    qDebug() << parser.isSet(op2);  // true
    qDebug() << parser.isSet(op3);  // true

    反之。当解析模式为ParseAsLongOptions时。"-abc"会被觉得是1个长命令,即"-abc"

    可是因为长命令应该是以"--"开头,所以以下的代码会出现异常,提示"未知的选项"

    QCommandLineOption op1("a");
    QCommandLineOption op2("b");
    QCommandLineOption op3("c");
    
    QCommandLineParser parser;
    parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
    parser.addOption(op1);
    parser.addOption(op2);
    parser.addOption(op3);
    parser.process(a);  // 抛出异常,程序退出:Unknown option 'abc'.


    Qt推荐使用ParseAsCompactedShortOptions模式。这也是默认的解析模式。而ParseAsLongOptions模式则是为了兼容而存在。


    二、带值的命令

    命令行參数通常就分为两种,带值的和不带值的。不带值的就直接注冊一个命令即可了。比方上面的

    QCommandLineOption op1("a");

    我们能够把这个"-a"理解为一个bool类型的命令。假设须要带值,则把值写在命令后面就可以,值和命令之间用等号或空格隔开,字符串能够用双引號括起来

    -a ABC
    -a=ABC

    继续看一段代码,如果命令行为"-a="C:/A B/Demo.exe""

    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      // -a="C:/A B/Demo.exe"
      QCommandLineOption op1("a");
      QCommandLineParser parser;
      parser.addOption(op1);
      parser.process(a); // 异常 Unexpected value after '-a'.
      qDebug() << parser.isSet(op1);
      qDebug() << parser.value(op1);
    
      MainWindow w;
      w.show();
    
      return a.exec();
    }

    因为我们定义的op1并没有说明其会有參数,而实际的命令行后面跟了个參数,解析器就会报错。Qt文档中也表示,解析器不支持可选參数。


    假设须要附带參数,则必须指定一个期望值

    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      // -a="C:/A B/Demo.exe"
      QCommandLineOption op1("a");
      op1.setValueName("path"); // 期望值是路径,设置了ValueName后。解析器会觉得此命令带值
      QCommandLineParser parser;
      parser.addOption(op1);
      parser.process(a);
      qDebug() << parser.value(op1);// "C:/A B/Demo.exe"
    
      MainWindow w;
      w.show();
    
      return a.exec();
    }


    设置了ValueName后,解析器就会觉得此命令带值,将会觉得下一个等号或空格后的值就是參数
    这个ValueName名字随便取,仅仅是起到一个指导性的作用。你甚至能够将它设置为"abc"

    另外,值能够有多个

    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      // -a="C:/A B/Demo.exe" -a "Hello world"
      QCommandLineOption op1("a");
      op1.setValueName("test");
      Q CommandLineParser parser;
      parser.addOption(op1);
      parser.process(a);
      qDebug() << parser.values(op1);// ("C:/A B/Demo.exe", "Hello world")
    
      MainWindow w;
      w.show();
    
      return a.exec();
    }

    还有QCommandLineParser的addHelpOption()、addVersionOption()都是加入显示命令版本号和帮助用的,一般仅仅有命令行程序才会用到吧,就不细说了。


    解析能够用parse()方法或process()方法,前者遇到不可解析的命令会返回false但不会抛出异常,后者则会抛出异常。

    最后。看一个比較完整的演示样例

    // -a --BBB -c -D=Jack --Age -m=Hello -m "World"
    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      QCommandLineOption op1("a");// 短名称,无參数
      QCommandLineOption op2("BBB");// 长名称,无參数
      QCommandLineOption op3(QStringList() << "c" << "CCC");// 多个名称。无參数
      QCommandLineOption op4("D", "", "Name");// 短名称,有參数,无默认值
      QCommandLineOption op5("Age", "", "", "18");// 长名称,有參数,有默认值
      QCommandLineOption op6("m", "", "."); // 短名称,有參数,无默认值
    
      QCommandLineParser parser;
      parser.addOption(op1);
      parser.addOption(op2);
      parser.addOption(op3);
      parser.addOption(op4);
      parser.addOption(op5);
      parser.addOption(op6);
      parser.process(a);
    
      qDebug() << parser.isSet(op1); // true
      qDebug() << parser.isSet("BBB"); // true
      qDebug() << parser.isSet("CCC"); // true
      qDebug() << parser.value(op4); // "Jack"
      qDebug() << parser.value(op5); // "18"
      qDebug() << parser.values(op6);// ("Hello", "World")
    
      qDebug() << parser.helpText();
      MainWindow w;
      w.show();
    
      return a.exec();
    }


  • 相关阅读:
    配置vCenter Server Appliance 6.7
    部署vCenter Server Appliance 6.7
    罗克韦尔 Allen-Bradley MicroLogix 1400 查看、设置IP
    centos7 部署 docker compose
    centos7 部署 docker ce
    docker 定时清理none镜像
    [CLR via C#]5.1 基元类型
    [CLR via C#]4. 类型基础及类型、对象、栈和堆运行时的相互联系
    [CLR via C#]1.6 Framework类库~1.9与非托管代码的互操作性
    [CLR via C#]1.5 本地代码生成器:NGen.exe
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7209171.html
Copyright © 2020-2023  润新知