使用 getopt_long(C ++),我如何编写长选项和短选项都需要参数的代码?

4
#include <iostream>
#include <getopt.h>

#define no_argument 0
#define required_argument 1 
#define optional_argument 2


int main(int argc, char * argv[])
{
  std::cout << "Hello" << std::endl;

  const struct option longopts[] =
  {
    {"version",   no_argument,        0, 'v'},
    {"help",      no_argument,        0, 'h'},
    {"stuff",     required_argument,  0, 's'},
    {0,0,0,0},
  };

  int index;
  int iarg=0;

  //turn off getopt error message
  opterr=1; 

  while(iarg != -1)
  {
    iarg = getopt_long(argc, argv, "svh", longopts, &index);

    switch (iarg)
    {
      case 'h':
        std::cout << "You hit help" << std::endl;
        break;

      case 'v':
        std::cout << "You hit version" << std::endl;
        break;

      case 's':
        std::cout << "You hit stuff" << std::endl;
        break;
    }
  }

  std::cout << "GoodBye!" << std::endl;

  return 0; 
}

输出:

./a.out -s
Hello
You hit stuff
GoodBye!

输出:

./a.out --stuff
Hello
./a.out: option `--stuff' requires an argument
GoodBye!

需要解决的冲突: 当命令后面没有跟随参数时,-s和--s都应该显示:./a.out: option `--stuff' requires an argument。但只有--stuff会显示?有人知道我错过了什么吗?

期望的结果:

./a.out -s
     Hello
     ./a.out: option `--stuff' requires an argument
      GoodBye!

./a.out --stuff
     Hello
     ./a.out: option `--stuff' requires an argument
     GoodBye!

只是一个小问题:可能不需要那些#define语句,因为当包含getopt.h时,相同名称的变量应该已经被声明为枚举类型,因此重新定义可能会引发错误。如果某些奇怪、过时或其他有缺陷的平台的getopt.h没有声明这些变量,则应该将#define语句包装在#ifdef内,检查仅在该特定平台上定义的某些变量。 - user2895783
2个回答

9
您的getopt_long调用指定了“svh”作为短选项,而应该是“s:vh”。冒号告诉getopt要求“s”的参数。

非常感谢。那个有效了,我想我没有仔细阅读手册。非常非常感激。 - stackoverflow

5

我非常确定你需要将"svh"替换为"s:vh"。根据Linux getopt_long的man页面,“optstring是一个包含合法选项字符的字符串。如果这样的字符后面跟着一个冒号,则该选项需要一个参数。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接