web-dev-qa-db-ja.com

Getoptオプションの引数?

オプションを入力するプログラムがあります-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);
        }   
    }
}

したがって、オプションの後にオプション以外の引数を入力すると、引数が出力されます。ただし、ユーザーがオプション以外の引数を指定しない場合は、char "string"を出力する必要があります(これが、OPT_LISTに二重コロンを配置する理由です)。しかし、これを行う方法がわからないので、どんな助けでも大歓迎です。

プログラムを実行するとどうなりますか。

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

C言語を使用してOSXでMacを実行しています。

8
pudumaster

「オプションのオプション値」機能は、GNU libc拡張機能であり、POSIXでは必要ありません。おそらく、Mac OSXに付属のlibcでは実装されていません。

Options引数は、このプログラムに有効なオプション文字を指定する文字列です。この文字列のオプション文字の後にコロン( ‘:’)を付けて、必須の引数を取ることを示すことができます。オプション文字の後に2つのコロン( ‘::’)が続く場合、その引数はオプションです。これはGNU拡張子です。

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

実際、POSIX.1-2008のセクション12.2「ユーティリティ構文ガイドライン」では、この機能を明示的に禁止しています。

ガイドライン7:オプション-引数はオプションであってはなりません。

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

15
Delan Azabani

getopt のドキュメントによると、引数付きのオプションに引数がない場合は:が返されます。また、一致する引数を使用してoptoptを設定します。

したがって、以下を使用します。

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;
}
8
reece

多分私はその質問を誤解しています。ユーザーがgetoptのデフォルトのエラー処理を乗り越えたいと思っているかのように読んでいます。その場合、OPT_LISTの先頭に:を含めるべきではありませんか?上記のコードは良いと思いますが、それでも印刷されると思います

./arg: option requires an argument -- d

それを抑制するために、OPT_LISTの先頭に:が必要ではありませんか?たとえば、これを変更します。

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

これに:

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

私が間違っている場合は私を訂正してください。

4
Spork Schivago

このソリューションを試してください。わたしにはできる。オプションの引数を持つオプションとしてオプション '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: ;
  }

ここではいくつかの例を示します。

./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'
0
tomas zubrik