【问题标题】:Checking for specific command line arguments in C++在 C++ 中检查特定的命令行参数
【发布时间】:2019-04-03 17:01:14
【问题描述】:

我正在构建一个 CLI 应用程序,它应该执行与此类似的操作:

./app

Welcome to the app, Type -h or --help to learn more.

./app -h

list of commands:...

这是我正在尝试构建的代码:

#include <iostream>

using namespace std;

int main(int argc, char** argv)  {

   cout << "Welcome to the app. Type -h or --help to learn more\n";

   if(argv == "-h" || argv == "--help") {
      cout << "List of commands:...";
   }
  return 0;
}

但是当我尝试编译 gcc 时会出现以下错误:

error: comparison between distinct pointer types ‘char**’ and ‘const char*’ lacks a cast [-fpermissive]
    if(argv == "-h" || argv == "--help") {
               ^~~~
error: comparison between distinct pointer types ‘char**’ and ‘const char*’ lacks a cast [-fpermissive]
    if(argv == "-h" || argv == "--help") {
                               ^~~~~~~~

【问题讨论】:

  • 用例如argv == "-h" 你比较两个永远不会相等的 指针。如错误消息中所述,指针也具有不同的类型。我建议你 get a couple of good books 阅读,因为他们应该有关于你想要什么的信息。如果您稍微搜索一下,还有很多关于如何做到这一点的教程和示例。
  • 看看getopt()
  • 假设-h 是第一个命令行参数-并且您已经检查argc 以确保提供了这样的参数-您需要执行strcmp(argv[1], "-h")。更好的是,不要使用 C 字符串比较函数,而是弄清楚如何使用 C++ std::string

标签: c++ command-line-arguments


【解决方案1】:

从 C++17 开始,编写此代码的最佳方式如下:

#include <iostream>
#include <string_view>

int main(int argc, char** argv) {
    using namespace std::literals;

    std::cout << "Welcome to the app. Type -h or --help to learn more\n";

    if (argv[0] == "-h"sv || argv[0] == "--help"sv) {
       std::cout << "List of commands:...";
    }
}

string_view 标头存在之前,您可以使用""s std::string 文字,它产生与上述相同的代码,只是包括string 标准标头并将"…"sv 更改为"…"s .不幸的是,这样的代码会导致冗余分配,但在这个特定的示例中,这是无关紧要的。

【讨论】:

    【解决方案2】:

    argv 是指向 char* 的指针。

    您必须首先选择要访问的 argc 参数。

    例如第三个参数为 argv[2]。

    而且您不能在 char* 上使用 == 进行字符串比较,您必须使用 strcmp,或者从 char * 构造一个字符串对象,如下所示: 字符串 arg2 = argv[2];

    然后你可以做 arg2 == "--help"

    【讨论】:

    • argv[2]second 参数,考虑到 argv[0] 是命令的名称。您可能应该添加一个注释,以便在索引 argv 之前始终检查 argc
    • @A.Franzen argv[0] 始终是程序/命令的名称,根据 argc(其中包含传递的参数数量),您可以访问相应的参数。
    【解决方案3】:

    如果要使用 == 运算符,则需要遍历参数数组并将 char 数组转换为字符串

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char** argv)  {
    
        cout << "Welcome to the app. Type -h or --help to learn more\n";
    
        for(int i=0;i<argc;i++)
        {
            if(string(argv[i]) == "-h" || string(argv[i]) == "--help")
            {
                cout << "List of commands:...";
            }
        }
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      你不能像比较整数那样比较字符串!!! 使用strcmp/stricmp

      【讨论】:

      • C++ 有更多可读的方式来编写这段代码。你的断言“你不能像比较整数那样比较字符串”在 C++ 中是完全错误的,如果你添加更多的感叹号,也不会变得更加正确。
      猜你喜欢
      • 2017-03-10
      • 1970-01-01
      • 2012-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      相关资源
      最近更新 更多