1

我想获得此命令的选项:

my_cmd show --value true -D

为此,我需要检查两次选项(由于架构)。在第二遍期间,不可能正确检索与其选项对应的参数。在此示例中,在第二次传递期间,检索到的参数(对于 option --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"

任何帮助,将不胜感激。

谢谢!

4

2 回答 2

2

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

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

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

于 2012-08-08T15:42:00.863 回答
1

getopt重新排序参数并将在所有非选项参数之前返回所有选项参数,如手册中所述:

默认情况下,getopt()会在扫描时置换 argv 的内容,以便最终所有非选项都位于末尾。还实现了另外两种模式。如果 optstring 的第一个字符是 '+' 或设置了环境变量 POSIXLY_CORRECT,则一旦遇到非选项参数,选项处理就会停止。如果 optstring 的第一个字符是 '-',则每个非选项 argv 元素都被处理为就好像它是具有字符代码 1 的选项的参数一样。(这被编写为期望选项和其他 argv 元素的程序使用以任何顺序,并且关心两者的顺序。)特殊参数“--”强制结束选项扫描,而不管扫描模式如何。

由于 is 的正确长语法--value true--value=truetrue视为非选项参数并移到选项参数后面。

于 2012-08-08T15:39:18.327 回答