函数getopt_long_only()

第一次接触这个函数,是因为学习mjpg-streamer的源码。

函数作用:对命令行选项进行解析。

函数出处
头文件getopt.h中:

#include <getopt.h>
int getopt_long_only(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

参数介绍
optstring:短选项字符串
longopts: struct option数组,用于存放长选项参数
longindex:用于返回长选项在longopts结构体数组的索引值,用于调试;一般置为NULL

先介绍一下struct option

struct option {
    const char *name;          //长选项名
    int         has_arg;       //是否需要参数
    int        *flag;
    int         val;

};

参数has_arg的值:

# define no_argument                0       //if the option does not take an argument
# define required_argument      1        //if the option requires an argument

# define optional_argument      2        //if the option takes an optional argument

参数flag和val相互依赖,主要分两种情况:
(1)flag为NULL,val值用于确定该长选项,所以需要为长选项指定唯一的val值。这里也为长选项和短选项建立了桥梁。
(2)flag不为NULL,则将val值存放到flag所指向的存储空间,用于标识该长选项出现过。

返回值
(1)短选项: 程序中使用短选项,则返回短选项字符(如‘n’),当需要参数时,则在返回之前将参数存入到optarg中。
(2)0/val值: 程序中使用长选项,返回值根据flag和val值确定。
①当flag为NULL时,返回val值(所以根据val值做不同处理,即val必须唯一)。当val值等于短选项值,则可以使用短选项解析函数解析长选项。
②当flag不为NULL时,则将val值存入flag所指向的存储空间,getopt_long_only()返回0
(3)?: 出现未定义的长选项,函数返回“?”

(4)-1: 解析完所有参数之后返回-1(即当函数解析完参数返回-1之后跳出while循环)

实例
实例1:文件getopt.c源码:

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h> //getopt_long()头文件位置

int main(int argc, char** argv)
{
        const char *optstring = "n:v";
        int c, deb, index;
        struct option opts[] = {
                {"username", required_argument, NULL, 'n'},
                {"version", no_argument, NULL, 'v'},
                {"debug", no_argument, &deb, 1},
                {0,0,0,0}
        };

        while( (c = getopt_long_only(argc, argv, optstring, opts, &index)) != -1)
        {
                switch(c)
                {
                        case 'n':                   //使用-n 或者 --username 指定用户名
                                printf("username is %s\n",optarg);
                                break;
                        case 'v':                  //使用-v 或者--version,输出版本号
                                printf("version is 0.0.1 \n");
                                break;
                        case 0:                     //flag不为NULL
                                printf("debug is %d\n",deb);
                                break;
                        case '?':                     //选项未定义
                                printf("?\n");
                                break;
                        default:
                                printf("c is %d\n",c);
                                break;
                }
        }
        return 0;
}

编译运行结果分析:

$ ./getopt -n won
username is won         
$ ./getopt -v
version is 0.0.1
$ ./getopt -w
./getopt: unrecognized option '-w'
?
$ ./getopt -d
debug is 1

实例2:文件getopt_1.c源码:(有点问题)

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char** argv)
{
        const char *optstring="n:v";
        int c,deb,index;
        struct option opts[]={
                {"username",required_argument,0,0},
                {"n",required_argument,0,0},
                {"version",no_argument,0,0},
                {"v",no_argument,0,0},
                {"debug",no_argument,0,0},
                {"d",no_argument,0,0},
                {"help",no_argument,0,0},
                {"h",no_argument,0,0}
        };

        while((c=getopt_long_only(argc,argv,optstring,opts,&index))!=-1)
        {
                switch(index){
                        //-n或者--username
                        case 0:
                        case 1:
                                printf("username:%s\n",optarg);
                                break;
                                //-v或者--version
                        case 2:
                        case 3:
                                printf("version:1.0.0\n");
                                break;
                                //-d or --debug
                        case 4:
                        case 5:
                                printf("debug:yes\n");
                                break;
                                //-h or --help
                        case 6:
                        case 7:
                                printf("Help:?\n");
                                break;
                        default:
                                printf("other:%d\n",index);
                                break;
                }
        }
        return 0;

}

执行结果分析:

$ ./getopt_1 --username won --version -d -h
username:won
version:1.0.0
debug:yes
Help:?

$ ./getopt_1 -j
Segmentation fault
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章