C Getopt : Wrong argument corresponding to its option

标签 c linux command-line-arguments getopt

我想获取此命令的选项:

my_cmd show --value true -D

为此,我需要通过选项两次(由于架构)。在第二遍期间,无法正确检索与其选项对应的参数。 在此示例中,在第二次传递期间检索到的参数(对于选项 --value)是 -D 而不是 true

第一关:

void getoptions (int argc, char **argv, globalargs_t* globalargs) {

    static const char *optstring = "vDqnd:c:f:o:h?:";

    static const struct option longopts[] = {
        { "help",         no_argument,        NULL,    'h' },
        { "Debug",        no_argument,        NULL,    'D'},
        { "verbose",    no_argument,        NULL,    'v'},
        { "quiet",        no_argument,        NULL,    'q'},
        { "noheader",    no_argument,        NULL,    0},
        { "delimiter",    required_argument,     NULL,    0},
        { "columns",    required_argument,    NULL,    0},
        { "filter",        required_argument,    NULL,    0},
        { "order",        required_argument,    NULL,    0},
        { "getid",        no_argument,        NULL,    'i'},
        { NULL,            no_argument,        NULL,    0 }
    };

    int opt = 0;
    int longindex = 0;
    //opterr = 0;

    /* Process the arguments with getopt_long(), then populate globalargs-> */
    opt = getopt_long( argc, argv, optstring, longopts, &longindex );
    while( opt != -1 ) {
        switch( opt ) {
            case '?':
                break;
            case 'D':
                globalargs->debug = 1;    /* true */
                break;
            case 'v':
                globalargs->verbose++;
                break;
            case 'q':
                globalargs->quiet = 1;
                break;
            case 'i':
                globalargs->id = 1;
                break;
            case 'h':
                globalargs->help = 1;
                break;
            case 0:        /* long option without a short arg */
                if( strcmp( "Debug", longopts[longindex].name ) == 0 ) {
                    globalargs->debug = 1;
                }
                if( strcmp( "verbose", longopts[longindex].name ) == 0 ) {
                    globalargs->verbose = 1;
                }
                if( strcmp( "quiet", longopts[longindex].name ) == 0 ) {
                    globalargs->quiet = 1;
                }
                if( strcmp( "noheader", longopts[longindex].name ) == 0 ) {
                    globalargs->noheader = 1;
                }
                if( strcmp( "delimiter", longopts[longindex].name ) == 0 ) {
                    globalargs->delimiter = *optarg;
                }
                if( strcmp( "filter", longopts[longindex].name ) == 0 ) {
                    globalargs->filter = optarg;
                }
                if( strcmp( "order", longopts[longindex].name ) == 0 ) {
                    globalargs->order = optarg;
                }
                if( strcmp( "columns", longopts[longindex].name ) == 0 ) {
                    globalargs->columns = optarg;
                }
                break;
            default:
                /* You won't actually get here. */
                break;
        }
        opt = getopt_long( argc, argv, optstring, longopts, &longindex );
    }
    if (optind < argc) {
        while (optind < argc) {
            globalargs->actions[globalargs->actionsindex] = argv[optind++];
            globalargs->actionsindex++;
        }
    }
}

第二遍:

void getspecificoptions(int argc, char **argv, globalargs_t* globalargs) {
    static const char *optstring = ":n:d:v:d";

    static const struct option longopts[] = {
        { "name",                required_argument,     NULL,    'n'},
        { "domain",                required_argument,    NULL,    0},
        { "value",                required_argument,    NULL,    0},
        { "defined_value",        required_argument,    NULL,    0},
        { NULL,                    no_argument,        NULL,    0 }
    };

    optind = 1;
    int opt = 0;
    int longindex = 0;

    /* Process the arguments with getopt_long(), then populate globalargs-> */
    opt = getopt_long( argc, argv, optstring, longopts, &longindex );
    while( opt != -1 ) {
        switch( opt ) {
            case 'n':
                /* If used in update/add => must be still a filter */
                globalargs->filter = strcat(globalargs->filter,"cluster.name=");
                globalargs->filter = strcat(globalargs->filter, optarg);
                if(!globalargs->table || strcmp(globalargs->table, "cluster") == 0 ) {
                    globalargs->table = "cluster";
                }
                else {
                    clmError(&t, "dbm-command", -1, "Incompatible options.");
                    exit(EXIT_FAILURE_OPTIONS);
                }
                break;
            case 0:        /* long option without a short arg */
                if( strcmp( "domain", longopts[longindex].name ) == 0 ) {

                    }
                    else {
                        char* f = my_new(500*sizeof(char));
                        f = strcat(f, "cluster.dns_domain=");
                        f = strcat(f, optarg);
                        globalargs->actions[globalargs->actionsindex] = f;
                        globalargs->actionsindex++;
                    }
                    if(strcmp(globalargs->table,"") == 0 || strcmp(globalargs->table, "cluster") == 0 ) {
                        globalargs->table = "cluster";
                    }
                    else {
                        clmError(&t, "dbm-command", -1, "Incompatible options.");
                        exit(EXIT_FAILURE_OPTIONS);
                    }
                }
                if( strcmp( "value", longopts[longindex].name ) == 0 ) {
                    if(strcmp(globalargs->actions[0], "show") == 0 || strcmp(globalargs->actions[0], "delete") == 0 ) {
                        globalargs->filter = realloc(globalargs->filter, strlen(globalargs->filter) + strlen(optarg) + strlen("cluster_profile.value=") + 1);
                        globalargs->filter = strcat(globalargs->filter,"cluster_profile.value=");
                        globalargs->filter = strcat(globalargs->filter, optarg);
                    }
                    else {
                        char* act = my_new(strlen(optarg) + strlen("cluster_profile.value=") + 1U);
                        act = strcat(act, "cluster_profile.value=");
                        act = strcat(act, optarg);
                        globalargs->actions[globalargs->actionsindex] = act;
                        globalargs->actionsindex++;
                    }
                    if(strcmp(globalargs->table,"") == 0 || strcmp(globalargs->table, "profile") == 0 ) {
                        globalargs->table = "profile";
                    }
                    else {
                        clmError(&t, "dbm-command", -1, "Incompatible options.");
                        exit(EXIT_FAILURE_OPTIONS);
                    }
                }
                if( strcmp( "defined_value", longopts[longindex].name ) == 0 ) {
                    /* If used in update/add => must be still a filter */
                    globalargs->filter = strcat(globalargs->filter,"cluster_profile.defined_value=");
                    globalargs->filter = strcat(globalargs->filter, optarg);

                    if(!globalargs->table || strcmp(globalargs->table, "profile") == 0 ) {
                        globalargs->table = "profile";
                    }
                    else {
                        clmError(&t, "dbm-command", -1, "Incompatible options.");
                        exit(EXIT_FAILURE_OPTIONS);
                    }
                }
                break;
        }
        opt = getopt_long( argc, argv, optstring, longopts, &longindex );
    }
}

在这些传递之后,我有 globalargs->filter="-D"

如有任何帮助,我们将不胜感激。

谢谢!

最佳答案

必须将 optind 重置为 0 而不是 1。第一次通过时,限定标志被解析,但第二次则没有,因为 optind 是 1 而不是 0。将其设置为 0 会重新解析字符串。

optstring 的第一个字符也必须是 + 或 -(在前导冒号之前)以防止参数被重新排序。

这一切都假设您使用的是 GNU 的 getopt_long。

关于C Getopt : Wrong argument corresponding to its option,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11867636/

相关文章:

C++如何传递命令行参数来读取txt文件

windows - 通过 WMI(Windows 管理规范)检索另一个用户拥有的进程的命令行参数

c - 读取 pgm 文件

objective-c - 在 switch 语句中声明变量

php - 在 Mac OS X 上为 PHP --enable-zip 安装 zip 扩展

linux - 如何获得在 Linux 上运行的全功能 PowerShell?

c - 从数组中随机选择两个元素并交换C中的值

c - 如何访问声明为结构类型的指针变量的值

c - 在 C 中运行 Ruby

go - 将 .go-file 作为附加参数传递给 `go run`