C语言 Getopt 可选参数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19604413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:50:14  来源:igfitidea点击:

Getopt optional arguments?

cargumentsoptiongetoptoptional

提问by pudumaster

I have a program where you enter an option -dand then whether or not you supply a non-optional argument after the option, do something.
Heres my code:

我有一个程序,您可以在其中输入一个选项 -d,然后无论您是否在选项后提供一个非可选参数,都可以做一些事情。
这是我的代码:

#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>

#define OPT_LIST "d::" 

int main (int argc, char *argv[])
{
    int c;
    char string[] = "blah";

    while ((c = getopt (argc, argv, OPT_LIST)) != -1)
    {
        switch (c)
        {
            case 'd':
                    printf("%s\n", optarg);
                    break;

            case '?':
                fprintf(stderr, "invalid option\n");
                exit(EXIT_FAILURE);
        }   
    }
}

So if you enter a non-optional argument after the option, it prints the argument. But I want it to print out the char "string" if the user doesn't supply a non-optional argument (this is why I put the double colon in the OPT_LIST). But I'm not sure how to do this so any help would be greatly appreciated.

因此,如果您在选项后输入一个非可选参数,它会打印该参数。但是我希望它在用户不提供非可选参数的情况下打印出字符“字符串”(这就是我将双冒号放在 OPT_LIST 中的原因)。但我不知道如何做到这一点,所以任何帮助将不胜感激。

Heres what happens when I run the program:

这是我运行程序时发生的情况:

user:desktop shaun$ ./arg -d hello
hello
user:desktop shaun$ ./arg -d 
./arg: option requires an argument -- d
invalid option

I'm running a Mac with OS X using C language.

我正在使用 C 语言在 OS X 上运行 Mac。

回答by Delan Azabani

The "optional value of an option" feature is only a GNU libc extension, not required by POSIX, and is probably simply unimplemented by the libc shipped with Mac OS X.

“选项的可选值”功能只是 GNU libc 扩展,POSIX 不需要,并且可能只是 Mac OS X 附带的 libc 未实现。

The options argument is a string that specifies the option characters that are valid for this program. An option character in this string can be followed by a colon (‘:') to indicate that it takes a required argument. If an option character is followed by two colons (‘::'), its argument is optional; this is a GNU extension.

options 参数是一个字符串,用于指定对该程序有效的选项字符。此字符串中的选项字符后可以跟一个冒号 (':') 以指示它需要一个必需的参数。如果选项字符后跟两个冒号 ('::'),则其参数是可选的;这是一个 GNU 扩展。

https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

In fact, POSIX.1-2008, section 12.2, "Utility Syntax Guidelines", explicitly forbids this feature:

事实上,POSIX.1-2008,第 12.2 节,“实用程序语法指南”,明确禁止此功能:

Guideline 7: Option-arguments should not be optional.

准则 7:选项参数不应该是可选的。

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02

回答by reece

According to the getoptdocumentation, it will return :if an option with an argument does not have one. It also sets optoptwith the matching argument.

根据getopt文档,:如果带参数的选项没有选项,它将返回。它还设置optopt了匹配的参数。

Therefore, use:

因此,使用:

int main (int argc, char *argv[])
{
    int c;
    while ((c = getopt (argc, argv, "d:f:")) != -1)
    {
        switch (c)
        {
            case 'd':
            case 'f':
                printf("option -%c with argument '%s'\n", c, optarg);
                break;
            case ':':
                switch (optopt)
                {
                case 'd':
                    printf("option -%c with default argument value\n", optopt);
                    break;
                default:
                    fprintf(stderr, "option -%c is missing a required argument\n", optopt);
                    return EXIT_FAILURE;
                }
                break;
            case '?':
                fprintf(stderr, "invalid option: -%c\n", optopt);
                return EXIT_FAILURE;
        }
    }
    return EXIT_SUCCESS;
}

回答by Spork Schivago

Maybe I'm misunderstanding the question. I'm reading it as though the user wants to over ride getopt's default error handling. If that is the case, shouldn't there be a : in the beginning of their OPT_LIST? I think the code above is good, however, I think it will still print

也许我误解了这个问题。我正在阅读它,好像用户想要超越 getopt 的默认错误处理。如果是这样的话,在他们的 OPT_LIST 的开头不应该有一个 : 吗?我认为上面的代码很好,但是,我认为它仍然会打印

./arg: option requires an argument -- d

To surpress that, don't we need a : at the beginning of the OPT_LIST? For example, changing this:

为了抑制这一点,我们不需要在 OPT_LIST 的开头添加 : 吗?例如,改变这个:

while ((c = getopt (argc, argv, "d:f:")) != -1)

to this:

对此:

while ((c = getopt (argc, argv, ":d:f:")) != -1)

Correct me if I'm wrong.

如果我错了纠正我。

回答by tomas zubrik

Try this solution. It works for me. Consider option 'z' as option with optional argument.

试试这个解决方案。这个对我有用。将选项“z”视为带有可选参数的选项。

int c;
opterr = 0; //if (opterr != 0) (which it is by default), getopt() prints its own error messages for invalid options and for missing option arguments.
while ((c = getopt (argc, argv, "x:y:z:")) != -1)
    switch (c)
    {
        case 'x':
        case 'y':
        case 'z':
            printf("OK ... option -%c with argument '%s'\n", c, optarg);
            break;

        case '?':
            if (optopt == 'x' || optopt == 'y')
                fprintf (stderr, "ERR ... Option -%c requires an argument.\n", optopt);
            else if(optopt == 'z' && isprint(optopt))
            {
                printf("OK ... option '-z' without argument \n");
                break;
            }
            else if (isprint (optopt))
                fprintf (stderr, "ERR ... Unknown option `-%c'.\n", optopt);
            else
                fprintf (stderr, "ERR ... Unknown option character `\x%x'.\n", optopt);
            return -1;
        default: ;
  }

Here are some examples:

这里有些例子:

./prog -x
    ERR ... Option -x requires an argument.

./prog -y
    ERR ... Option -x requires an argument.

./prog -z
    OK ... option '-z' without argument

./prog -x aaa
    OK ... option -x with argument 'aaa'

./prog -y bbb -x aaa
    OK ... option -y with argument 'bbb'
    OK ... option -x with argument 'aaa'

./prog -x aaa -y bbb -z
    OK ... option -x with argument 'aaa'
    OK ... option -y with argument 'bbb'
    OK ... option '-z' without argument

./prog -x aaa -y bbb -z ccc
    OK ... option -x with argument 'aaa'
    OK ... option -y with argument 'bbb'
    OK ... option -z with argument 'ccc'