在C ++中,如何只使用长选项具有必需的参数?(In C++, how to use only lo

2019-07-29 01:25发布

在C ++程序,我想有一个“长仅”有必需的参数选项。 下面是用我的小例子, getopt_long() ,但它不工作:

#include <getopt.h>
#include <cstdlib>
#include <iostream>
using namespace std;

void help (char ** argv)
{
  cout << "`" << argv[0] << "` experiments with long options." << endl;
}

void parse_args (int argc, char ** argv, int & verbose, int & param)
{
  int c = 0;
  while (1)
  {
    static struct option long_options[] =
      {
        {"help", no_argument, 0, 'h'},
        {"verbose", required_argument, 0, 'v'},
        {"param", required_argument, 0, 0}
      };
    int option_index = 0;
    c = getopt_long (argc, argv, "hv:",
                     long_options, &option_index);
    cout << "c=" << c << endl;
    if (c == -1)
      break;
    switch (c)
    {
    case 0:
      if (long_options[option_index].flag != 0)
        break;
      printf ("option %s", long_options[option_index].name);
      if (optarg)
        printf (" with arg %s", optarg);
      printf ("\n");
      break;
    case 'h':
      help (argv);
      exit (0);
    case 'v':
      verbose = atoi(optarg);
      break;
    case 'param':
      param = atoi(optarg);
      break;
    case '?':
      abort ();
    default:
      abort ();
    }
  }
}

int main (int argc, char ** argv)
{
  int verbose = 0;
  int param = 0;
  parse_args (argc, argv, verbose, param);
  cout << "verbose=" << verbose << " param=" << param << endl;
  return EXIT_SUCCESS;
}

我用这个命令(gcc版本4.1.2 20080704的Red Hat 4.1.2-46)编译:

g++ -Wall test.cpp

它告诉我:

test.cpp:44:10: warning: character constant too long for its type

这里是结果:

$ ./a.out -v 2 --param 3
c=118
c=0
option param with arg 3
c=-1
verbose=2 param=0

我试图使它在工作ideone但它甚至不认识的选项-v

正如在他trojanfoe表示意见的另一个问题,它应该是可能的,因为的GNU tar做它用“长仅”选项。 然而,GNU焦油使用argp ,我很难理解它的源代码 。

可能有人给我这样的作品,与GNU一个小例子, getopt_long()argp()

Answer 1:

有两个问题:

  1. 根据示例代码(你的链接),在结构中定义的最后一个选项必须是{0,0,0,0} 我建议改变的定义

     static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"verbose", required_argument, 0, 'v'}, {"param", required_argument, 0, 0}, {0,0,0,0} }; 
  2. (更重要的),你必须包括实际处理的“参数”选项的代码。 你这样做,在'0'的情况下:

     case 0: if (long_options[option_index].flag != 0) break; if (strcmp(long_options[option_index].name,"param") == 0) param = atoi(optarg); break; 

正如你可以看到我用strcmp函数来比较字符串; 对,你需要#include <cstring> 。 顺便说一句,你还需要#include <cstdio>为你使用printf

随着这些变化的地方,程序正确工作对我来说(在GCC 4.5.1测试)。



Answer 2:

在你的case语句,你使用:

case 'param':

这是给你的警告,因为编译器需要在那个地方的单个字符。



Answer 3:

事实上,我意识到,我应该检查的价值option_indexc的值为0 ,像这样。 这种情况是不是在GNU库的例子,所以在这里它是:

switch (c)
{
case 0:
  if (long_options[option_index].flag != 0)
    break;
  if (option_index == 2)
  {
    param = atoi(optarg);
    break;
  }
case 'h':
  help (argv);
  exit (0);
case 'v':
  verbose = atoi(optarg);
  break;
case '?':
  abort ();
default:
  abort ();
}


Answer 4:

另一个解决方案是使用在结构选项定义的“标志”件值。

设置你的选项,如下面:

int param_flag = 0;

{"param", required_argument, &param_flag, 1}

然后;

case 0:
    if (param_flag == 1) {
        do_something;
    }

见男子getopt_long关于结构选项的详细信息。



文章来源: In C++, how to use only long options with a required argument?