【问题标题】:Using getopt in C for command line arguments在 C 中使用 getopt 作为命令行参数
【发布时间】:2015-03-23 15:00:08
【问题描述】:

我正在尝试接受命令行参数。如果我想有多个可选的命令行参数,我将如何去做?例如,您可以通过以下方式运行程序: (每个实例都需要 a,但 -b -c -d 可以以任意顺序任意给出)

./myprogram -a
./myprogram -a -c -d
./myprogram -a -d -b

我知道 getopt() 的第三个参数是选项。我可以将这些选项设置为“abc”,但是我设置开关盒的方式会导致循环在每个选项处中断。

【问题讨论】:

  • 你能展示你的开关盒吗?
  • 请显示您的循环和switch 块,因为这是您的循环过早终止。通常循环只检查getopt是否返回-1,将返回值赋给一个变量以在switch语句中使用。
  • IMO:检索命令行参数的最佳方法是使用 make 使用 argc 检索参数总数并使用 *argv[] 检索参数。其中 argc 是 argv 中的项目数,argv[0] 是程序编号,argv[argc] 将是一个空指针,指示命令行参数列表的结尾

标签: c debugging command-line-arguments getopt getopt-long


【解决方案1】:

getopt() 而言,顺序无关紧要。重要的是您对getopt() 的第三个参数(即:它的格式字符串)是正确的:

以下格式字符串都是等价的:

"c:ba"
"c:ab"
"ac:b"
"abc:"

在您的特定情况下,格式字符串只需要类似于"abcd",并且正确填充了switch() 语句。

以下最小示例¹会有所帮助。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int
main (int argc, char **argv)
{
  int aflag = 0;
  int bflag = 0;
  char *cvalue = NULL;
  int index;
  int c;

  opterr = 0;

  while ((c = getopt (argc, argv, "abc:")) != -1)
  {
    switch (c)
      {
      case 'a':
        aflag = 1;
        break;
      case 'b':
        bflag = 1;
        break;
      case 'c':
        cvalue = optarg;
        break;
      case '?':
        if (optopt == 'c')
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "Unknown option `-%c'.\n", optopt);
        else
          fprintf (stderr,
                   "Unknown option character `\\x%x'.\n",
                   optopt);
        return 1;
      default:
        abort ();
      }
  }

  printf ("aflag = %d, bflag = %d, cvalue = %s\n",
          aflag, bflag, cvalue);

  for (index = optind; index < argc; index++)
    printf ("Non-option argument %s\n", argv[index]);
  return 0;
}

¹Example taken from the GNU manual

【讨论】:

  • 即使switch 在逻辑上是一个单独的语句,我也不会在其主体周围没有大括号的情况下编写while 循环。不过,这是一个细节点,在某种程度上是偏好。否则代码非常好。您在报告未知选项时对细节的关注令人印象深刻! (我通常不会那么小心。OTOH,我通常让getopt() 报告错误 - 我没有设置opterr = 0;。)报告预期用法是个好主意:fprintf(stderr, "Usage: %s [-ab][-c name] [file ...]\n", argv[0]); 当错误被检测到。
  • 对不起,我是 C 新手,变量 aflag bflag 等的用途是什么
  • 另外我想我不明白如果有中断它是如何处理多个标志的?例如,如果我调用 -a -b -c 它不会命中 -a 然后在命中 b 和 c 的 case 语句之前中断循环?
  • @sudobangbang break 语句只会跳出循环或 switch 语句的单个级别/深度。上例中的 break 语句将跳出 @9​​87654334@ 语句,但不会跳出包含它的 while 循环。
猜你喜欢
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
相关资源
最近更新 更多