使用多个参数解析命令行选项 [getopt?]

Posted

技术标签:

【中文标题】使用多个参数解析命令行选项 [getopt?]【英文标题】:Parsing command line options with multiple arguments [getopt?] 【发布时间】:2013-03-06 04:43:16 【问题描述】:

我需要我的程序从命令行获取几个参数,语法如下:

getpwd -l user1 user2 ... -L -X -S...

所以,我需要让-l 选项背后的用户。我尝试使用getopt,但运气不佳,它仅在我将其他选项放在-l 之前才有效:

getpwd -L -X -S ... -l user1 user2 ...

我的代码(-l-S):

    while((c = getopt(argc, argv, "l:S")) != -1)
    switch(c)
        case 'l':
            index = optind-1;
            while(index < argc)
                next = strdup(argv[index]); /* get login */
                index++;
                if(next[0] != '-')         /* check if optarg is next switch */
                    login[lcount++] = next;
                
                else break;
            
            break;
        case 'S':
            sflag++;                        /* other option */
            break;
        case ':':                           /* error - missing operand */
            fprintf(stderr, "Option -%c requires an operand\n", optopt);
            break;
        case '?':                           /* error - unknown option */
            fprintf(stderr,"Unrecognized option: -%c\n", optopt);
            break;
      
   

optoptoptindextern int

所以,问题是:我可以使用getopt() 函数(或getopt_long())吗?还是我必须编写自己的解析器才能得到我需要的东西?

【问题讨论】:

如果您对每个-l 一个用户没问题,您可以让用户根据需要使用尽可能多的-l 选项。 遗憾的是,该程序的规范说它必须与每个-l的多个用户一起使用 【参考方案1】:

以下函数将为参数列表中的单个选项生成 argc、argv 对:

void GetArgsList (int argc, char *argv[], int* o_argc, char*** o_argv)

    char** ret = NULL;
    int i;
    int count = 0;

    for (i = optind - 1; i < argc ; ++i)
    
        if (argv[i][0]=='-')
        
            break;
        
        else
        
            if (NULL == ret)
            
                ret = &argv[i];
            
            count++;
        
    

    optind = i - 1;

    if (o_argc)
    
        *o_argc = count;
    

    *o_argv = ret;

【讨论】:

【参考方案2】:

我写了一个用于解析命令行参数的 C 库(GPL 许可):

https://github.com/Vincenzo1968/myoptParser

https://github.com/Vincenzo1968/myoptParser/blob/master/how_to_use.md

您可以指定选项接受的最小和最大参数数量。 您还可以指定一个选项采用零个或多个参数(或一个或多个、两个或多个,等等)。 当然,您可以指定固定数量的参数:零、一、二等。

您还可以指定参数的类型:字符串、整数或浮点数。 解析器检查指定的数字和类型是否匹配,否则返回错误。

解析器还允许您指定是否需要某个选项。 您终于可以指定互斥选项了。

【讨论】:

【参考方案3】:

您的代码实际上非常非常接近工作。您唯一缺少的是getopt 只希望您在-l 之后使用一个参数,因此在-l 的第一个参数之后继续命令行解析。由于您背着它并提出更多参数,因此您必须告诉getopt 从哪里重新开始解析命令行。

getopt 将该信息存储在全局变量optind 中。当我添加该行时:

optind = index - 1;

在您的l 案例中的break; 之前,您的代码开始工作。

【讨论】:

出于某种原因optind = index-1 为我工作......我明天会更仔细地研究它。但是非常感谢。我很惊讶这个工作......我发现到处都不能以这种方式使用 getopts() :D 抱歉,您完全正确,应该是optind - 1。我的测试中的一个缺陷;我忘了测试以下选项是否已正确解析。我会解决的。

以上是关于使用多个参数解析命令行选项 [getopt?]的主要内容,如果未能解决你的问题,请参考以下文章

使用getopt命令解析shell脚本的命令行选项

使用 getopts (bash) 的多个选项参数

C语言linux getopt_long()函数(命令行解析)(getoptgetopt_long_only)(短选项 -,长选项 --)(option结构体)

shell 脚本参数解析之 getopt getopts

Perl模块 Getopt::Long 解析

在 C 中处理参数前后的命令行选项