在C ++中,如何仅将长选项与必需参数一起使用? [英] In C++, how to use only long options with a required argument?

查看:73
本文介绍了在C ++中,如何仅将长选项与必需参数一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 tar使用 argp ,我遇到了困难了解其源代码. /p>

有人可以给我一个使用GNU getopt_long()argp()的最小示例吗?

解决方案

有两个问题:

  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. (更重要的是,),您必须包含实际处理"param"选项的代码.在'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上进行了测试).

In a C++ program, I would like to have a "long-only" option with a required argument. Below is my minimal example using getopt_long(), but it's not working:

#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;
}

I compile it with this command (gcc version 4.1.2 20080704 Red Hat 4.1.2-46):

g++ -Wall test.cpp

It tells me this:

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

And here is the result:

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

I tried to make it work on ideone but it doesn't even recognize the option -v.

As indicated by trojanfoe in his comments of another question, it should be possible to use "long-only" options because GNU tar does it. However, GNU tar uses argp and I have difficulty understanding its source code.

Could someone give me a minimal example that works, with GNU getopt_long() or argp()?

解决方案

There are two problems:

  1. According to the example code (your link), the final option defined in the struct must be {0,0,0,0}. I recommend changing the definition to

    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. (And more importantly,) you must include code that actually processes the "param" option. You do that in the '0' case:

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

As you can see I use the strcmp function to compare the strings; for that you need to #include <cstring>. By the way, you also need #include <cstdio> for your use of printf.

With these changes in place, the program worked correctly for me (tested on GCC 4.5.1).

这篇关于在C ++中,如何仅将长选项与必需参数一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆