命令行选项解析函数(C语言):getopt()和getopt_long()

getopt函数

描述

getopt是用来解析命令行选项参数的,但是只能解析短选项: -d 100,不能解析长选项:--prefix

定义

int getopt(int argc, char * const argv[], const char *optstring);

参数

argc:main()函数传递过来的参数的个数
argv:main()函数传递过来的参数的字符串指针数组
optstring:选项字符串,告知 getopt()可以处理哪个选项以及哪个选项需要参数

optstring的格式意义:

char*optstring = “ab:c::”;
单个字符a         表示选项a没有参数            格式:-a即可,不加参数
单字符加冒号b:     表示选项b有且必须加参数      格式:-b 100或-b100,但-b=100错
单字符加2冒号c::   表示选项c可以有,也可以无     格式:-c200,其它格式错误
 

函数调用后,会返回以下四个变量

optarg —— 指向当前选项参数(如果有)的指针。
optind —— 再次调用 getopt() 时的下一个 argv指针的索引。
optopt —— 最后一个未知选项。
opterr ­—— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。

例子

#include<stdio.h>
#include<unistd.h>
#include<getopt.h>
int main(intargc, char *argv[])
{
    int opt;
    char *string = "a::b:c:d";
    while ((opt = getopt(argc, argv, string))!= -1)
    {  
        printf("opt = %c		", opt);
        printf("optarg = %s		",optarg);
        printf("optind = %d		",optind);
        printf("argv[optind] = %s
",argv[optind]);
    }  
}

编译运行

gcc tc.c -o tc
./tc -a100 -b 200 -c 300 -d

输出

opt = a        optarg = 100        optind = 2        argv[optind] = -b
opt = b        optarg = 200        optind = 4        argv[optind] = -c
opt = c        optarg = 300        optind = 6        argv[optind] = -d
opt = d        optarg = (null)     optind = 7        argv[optind] = (null)

 demo

bogon:testc macname$ sudo vi tc.c
bogon:testc macname$ 
bogon:testc macname$ gcc tc.c -o tc
bogon:testc macname$ ./tc
bogon:testc macname$ ./tc -a100 -b 200 -c 300 -d
opt = a        optarg = 100        optind = 2        argv[optind] = -b
opt = b        optarg = 200        optind = 4        argv[optind] = -c
opt = c        optarg = 300        optind = 6        argv[optind] = -d
opt = d        optarg = (null)        optind = 7        argv[optind] = (null)
bogon:testc macname$ ./tc -a -b 200 -c 300 -d
opt = a        optarg = -b        optind = 3        argv[optind] = 200
bogon:testc macname$ ./tc -b 200 -c 300 -d
opt = b        optarg = 200        optind = 3        argv[optind] = -c
opt = c        optarg = 300        optind = 5        argv[optind] = -d
opt = d        optarg = (null)        optind = 6        argv[optind] = (null)
bogon:testc macname$ ./tc -b 200 -c 300
opt = b        optarg = 200        optind = 3        argv[optind] = -c
opt = c        optarg = 300        optind = 5        argv[optind] = (null)
bogon:testc macname$ ./tc -b 200
opt = b        optarg = 200        optind = 3        argv[optind] = (null)

getopt_long函数

描述

包含 getopt 功能,增加了解析长选项的功能如:--prefix --help

 定义

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

参数

longopts    指明了长参数的名称和属性
longindex   如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值
struct option
struct option {
const char  *name;       /* 参数名称 */
int          has_arg;    /* 指明是否带有参数 */
int          *flag;      /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
int          val;        /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
}; 

返回

对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数

参数说明:

has_arg  指明是否带参数值,其数值可选:
no_argument         表明长选项不带参数,如:--name, --help
required_argument  表明长选项必须带参数,如:--prefix /root或 --prefix=/root
optional_argument  表明长选项的参数是可选的,如:--help或 –prefix=/root,其它都是错误

例子

int main(intargc, char *argv[])
{
    int opt;
    int digit_optind = 0;
    int option_index = 0;
    char *string = "a::b:c:d";
    static struct option long_options[] =
    {  
        {"reqarg", required_argument,NULL, 'r'},
        {"optarg", optional_argument,NULL, 'o'},
        {"noarg",  no_argument,         NULL,'n'},
        {NULL,     0,                      NULL, 0},
    }; 
    while((opt =getopt_long_only(argc,argv,string,long_options,&option_index))!= -1)
    {  
        printf("opt = %c		", opt);
        printf("optarg = %s		",optarg);
        printf("optind = %d		",optind);
        printf("argv[optind] =%s		", argv[optind]);
        printf("option_index = %d
",option_index);
    }  
}

demo 

bogon:testc macname$ sudo vi tc.c
bogon:testc macname$ 
bogon:testc macname$ gcc tc.c -o tc
bogon:testc macname$ ./tc --reqarg 100 --optarg=200 --noarg
opt = r        optarg = 100        optind = 3        argv[optind] =--optarg=200        option_index = 0
opt = o        optarg = 200        optind = 4        argv[optind] =--noarg        option_index = 1
opt = n        optarg = (null)        optind = 5        argv[optind] =(null)        option_index = 2
bogon:testc macname$ ./tc -reqarg 100 --optarg=200 --noarg
opt = r        optarg = 100        optind = 3        argv[optind] =--optarg=200        option_index = 0
opt = o        optarg = 200        optind = 4        argv[optind] =--noarg        option_index = 1
opt = n        optarg = (null)        optind = 5        argv[optind] =(null)        option_index = 2
bogon:testc macname$ ./tc -reqarg 100 --optarg --noarg
opt = r        optarg = 100        optind = 3        argv[optind] =--optarg        option_index = 0
opt = o        optarg = (null)        optind = 4        argv[optind] =--noarg        option_index = 1
opt = n        optarg = (null)        optind = 5        argv[optind] =(null)        option_index = 2
bogon:testc macname$ ./tc -reqarg=100 --optarg --noarg
opt = r        optarg = 100        optind = 2        argv[optind] =--optarg        option_index = 0
opt = o        optarg = (null)        optind = 3        argv[optind] =--noarg        option_index = 1
opt = n        optarg = (null)        optind = 4        argv[optind] =(null)        option_index = 2
bogon:testc macname$ ./tc -reqarg 100 --optarg 200 --noarg
opt = r        optarg = 100        optind = 3        argv[optind] =--optarg        option_index = 0
opt = o        optarg = (null)        optind = 4        argv[optind] =200        option_index = 1
opt = n        optarg = (null)        optind = 6        argv[optind] =(null)        option_index = 2
bogon:testc macname$ ./tc --reqarg 100 --optarg 200 --noarg
opt = r        optarg = 100        optind = 3        argv[optind] =--optarg        option_index = 0
opt = o        optarg = (null)        optind = 4        argv[optind] =200        option_index = 1
opt = n        optarg = (null)        optind = 6        argv[optind] =(null)        option_index = 2
bogon:testc macname$ ./tc --reqarg --optarg 200 --noarg
opt = r        optarg = --optarg        optind = 3        argv[optind] =200        option_index = 0
opt = n        optarg = (null)        optind = 5        argv[optind] =(null)        option_index = 2

getopt_long_only函数

getopt_long_only 函数与 getopt_long 函数使用相同的参数表,在功能上基本一致,只是 getopt_long 只将 --name 当作长参数,但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配。getopt_long_only 如果选项 -name 不能在 longopts 中匹配,但能匹配一个短选项,它就会解析为短选项。

参考:

https://www.cnblogs.com/chenliyang/p/6633739.html

https://blog.csdn.net/men_wen/article/details/61934376

https://blog.csdn.net/qq_16209077/article/details/51974448

https://blog.csdn.net/chaoyue1216/article/details/7329018