深入理解 getopt_long,getopt_long_only

getopt_long, getopt_long_only – 命令行解析函数,支持长选项解析

【说明】 getopt_long/getopt_long_onlygetopt 的泛集,getoptgetopt_long 的一个子集,getopt 支持的所有特性,getopt_long 都支持,包括错误打印、argv 元素顺序调整等;getopt_long 相比 getopt 增加了长选项的解析,具体如下:

1、形如:cmd [--create][--file] //对长选项的解析;
2、形如:cmd [--create a_argument][-file b_argument] //对长选项及长选项的参数解析;
3、形如:cmd [--create [a_argument]] //选项create的参数也是可选的情况解析
getopt_long_onlygetopt_long 的区别在于:getopt_long 仅仅只能将 “–” 开始的选项视为长选项,但 getopt_long_only 将"-“开头选项也会视为长选项,当长选项列表均不满足时,且短选项满足时,”-" 才会解析为短选项;

原型:

#define _GNU_SOURCE
#include 

extern char *optarg;
extern int optind, opterr, optopt;

int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);

描述:

1、注意相比 getopt,使用 getopt_long 需要加头文件 ;
2、getopt_long 除了会接受长选项,其他概念和 getopt 是一样的;
3、如果使用 getopt_long 想只接受短选项,设置 longoptsNULL 即可;如果只想接受长选项,相应地设置 optstringNULL 即可;
4、长选项名是可以使用缩写方式,比如:选项有 --file/--create,那么输入 --c/--cr/--cre 等均会被正确识别为 create 选项;
5、对于带参数的长选项格式是:--arg=param--arg param
6、longopts 是指向 struct option 数组的第一个元素的指针,struct option 定义在 中;
7、longindex 如果非 NULL,则是返回识别到 struct option 数组中元素的位置指针;

struct option的说明:

/*
name: 长选项名
has_arg: 是否带参数或可选参数,这个值在getopt.h中有宏定义,如下:
     # define no_argument        0
     # define required_argument  1
     # define optional_argument  2
flag: 确定函数返回值的情况,如果flag==NULL,则识别选项后返回val(常用的如:设置val为长命令的短命令字符);否则,识别后getopt_long返回0,flag指向一个设置到val的变量;
val: 设置为返回值,或者是flag指向的变量;这里要注意不要写-1到val,否则其作用是getopt_long返回-1,然后停止解析选项;

[注意] longopts的最后一个元素必须是全0填充,否则会报段错误
*/

struct option {
    const char *name; 
    int has_arg;  
    int *flag;
    int val;
};

返回值:

1、如果识别短选项,同 getopt 一样返回短选项字符;
2、如果识别长选项,根据 flag 的设置返回不同的内容,一般 flag 都设置为 NULL,返回 val
3、如果发生错误,如:未识别选项或者必须加参数的选项丢失参数,返回 ‘?’,如果在 optstring 中设置了第一个字符为 ‘:’,丢失参数返回 ‘:’,这个同 getopt 返回时一样的;
4、当缩写长选项引起歧义时或者不需要的选项强加了参数,都会返回 ‘?’;
5、返回 -1 表示选项处理全部结束;
6、如果在输入的 argv[] 中包含了独立的 “–” 字符串,同 getopt 一样,解析到这里返回 -1,停止选项的解析;

测试实例:

#include 
#include 
#include 

int main(int argc, char **argv)
{
        extern char *optarg;
        extern int optind, opterr, optopt;

        int c;
        int digit_optind = 0;

        while (1)
        {
                int this_option_optind= optind ? optind : 1;
                int option_index = 0;
                static struct option long_options[] =
                {
                        {"add", required_argument, NULL, 0},
                        {"append", no_argument, NULL, 0},
                        {"delete", required_argument, NULL, 0},
                        {"verbose", no_argument, NULL, 0},
                        {"create", required_argument, NULL, 'c'},
                        {"file", required_argument, NULL, 0},
                        {0, 0, 0, 0},
                };

                c = getopt_long(argc, argv, ":abc:d:012", long_options, &option_index);
                if (c == -1)
                        break;

                switch (c)
                {
                        case 0:
                                printf ("option %s", long_options[option_index].name);
                                if (optarg)
                                        printf (" with arg %s", optarg);
                                printf ("\n");
                                break;
                        case '0':
                        case '1':
                        case '2':
                                if (digit_optind != 0 && digit_optind != this_option_optind)
                                        printf ("digits occur in two different argv-elements.\n");
                                digit_optind = this_option_optind;
                                printf ("option %c\n", c);
                                break;
                        case 'a':
                                printf ("option a\n");
                                break;
                        case 'b':
                                printf ("option b\n");
                                break;
                        case 'c':
                                printf ("option c with value \"%s\"\n", optarg);
                                break;
                        case 'd':
                                printf ("option d with value \"%s\"\n", optarg);
                                break;
                        case '?':
                                break;
                        default:
                                printf ("?? getopt returned character code 0%o ??\n", c);
                }
        }

        if (optind < argc) {
                 printf ("non-option ARGV-elements: ");
                 while (optind < argc)
                          printf ("%s ", argv[optind++]);
                 printf ("\n");
         }

        exit(0);
}

运行自行操作测试

你可能感兴趣的:(C语言,linux)