getopt无法检测选项的缺失参数

fin*_*oop 17 c c++ getopt

我有一个程序,它采用各种命令行参数.为了简化起见,我们会说,它需要3个标志,-a,-b,和-c,并使用下面的代码来分析我的论点:

    int c;
    while((c =  getopt(argc, argv, ":a:b:c")) != EOF)
    {
        switch (c)
        {
             case 'a':
                 cout << optarg << endl;
                 break;
             case 'b':
                 cout << optarg << endl;
                 break;
             case ':':
                 cerr << "Missing option." << endl;
                 exit(1);
                 break;
        }
    }
Run Code Online (Sandbox Code Playgroud)

注意:a,和b后面的参数标志.

但是,如果我调用我的程序,我会遇到一个问题

./myprog -a -b parameterForB
Run Code Online (Sandbox Code Playgroud)

我忘记了parameterForA,返回-b参数ForA(由optarg表示),而参数FORB 被认为是没有参数的选项,而optind被设置为argv中parameterForB的索引.

在这种情况下,所需的行为':'是在没有找到参数后返回-a,并Missing option.打印到标准错误.但是,这仅发生在-a传递给程序的最后一个参数的事件中.

我想问题是:有getopt()没有办法假设没有选项可以开始-

Pot*_*ter 11

POSIX标准定义getopt.它说

如果[getopt]检测到缺少的option-argument,如果optstring的第一个字符是冒号,则返回冒号字符(':'),否则返回问号字符('?').

至于那个检测,

  1. 如果该选项是argv元素指向的字符串中的最后一个字符,那么optarg将包含argv的下一个元素,optind将增加2.如果optind的结果值大于argc,则表示缺少option-argument,getopt()将返回错误指示.
  2. 否则,optarg将指向argv元素中选项字符后面的字符串,optind将增加1.

它似乎getopt被定义为不做你想要的,所以你必须自己实施检查.幸运的是,你可以通过检查*optarg和改变optind自己来做到这一点.

int c, prev_ind;
while(prev_ind = optind, (c =  getopt(argc, argv, ":a:b:c")) != EOF)
{
    if ( optind == prev_ind + 2 && *optarg == '-' ) {
        c = ':';
        -- optind;
    }
    switch ( …
Run Code Online (Sandbox Code Playgroud)


Pho*_*ong 7

如果您使用的是C++,我建议使用boost :: program_option来解析命令行参数:

  • 我不是.我需要使用getopt (7认同)