zoukankan      html  css  js  c++  java
  • [C] getopt使用说明

    http://blog.csdn.net/weiwan123456/article/details/40891649

    (1) getopt函数

    定义int getopt(int argc, char * const argv[], const char *optstring);
    描述
    :getopt是用来解析命令行选项参数的,但是只能解析短选项: -d 100,不能解析长选项:--prefix
    参数:argc:main()函数传递过来的参数的个数
                 argv:main()函数传递过来的参数的字符串指针数组
                 optstring:选项字符串,告知 getopt()可以处理哪个选项以及哪个选项需要参数
    返回:如果选项成功找到,返回选项字母;如果所有命令行选项都解析完毕,返回-1;如果遇到选项字符不在optstring中,返回字符’?’;如果遇到丢失参数,那么返回值依赖于optstring中第一个字符,如果第一个字符是’:’则返回’:’,否则返回’?’并提示出错误信息。

    下边重点举例说明optstring的格式意义:

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

    上面这个optstring在传入之后,getopt函数将依次检查命令行是否指定了 -a, -b, -c(这需要多次调用getopt函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母)

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

    以上描述的并不生动,下边结合实例来理解:

    实例:

    [cpp] view plain copy
     
    1. <span style="font-size:14px;">#include<stdio.h>  
    2. #include<unistd.h>  
    3. #include<getopt.h>  
    4. int main(intargc, char *argv[])  
    5. {  
    6.     int opt;  
    7.     char *string = "a::b:c:d";  
    8.     while ((opt = getopt(argc, argv, string))!= -1)  
    9.     {    
    10.         printf("opt = %c ", opt);  
    11.         printf("optarg = %s ",optarg);  
    12.         printf("optind = %d ",optind);  
    13.         printf("argv[optind] = %s ",argv[optind]);  
    14.     }    
    15. }</span>  

    编译上述程序并执行结果:

    1、输入选项及参数正确的情况

    [cpp] view plain copy
     
    1. <span style="font-size:14px;">dzlab:~/test/test#./opt -a100 -b 200 -c 300 -d  
    2. opt = a         optarg = 100            optind = 2              argv[optind] = -b  
    3. opt = b         optarg = 200            optind = 4              argv[optind] = -c  
    4. opt = c         optarg = 300            optind = 6              argv[optind] = -d  
    5. opt = d         optarg = (null)         optind = 7              argv[optind] = (null)</span>  

    或者这样的选项格式(注意区别):

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./opt -a100 -b200 -c300 -d   
    2. opt = a         optarg = 100            optind = 2              argv[optind] = -b200  
    3. opt = b         optarg = 200            optind = 3              argv[optind] = -c300  
    4. opt = c         optarg = 300            optind = 4              argv[optind] = -d  
    5. opt = d         optarg = (null)         optind = 5              argv[optind] = (null)  

    选项a是可选参数,这里不带参数也是正确的

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./opt -a -b 200 -c 300 -d     
    2. opt = a         optarg = (null)         optind = 2              argv[optind] = -b  
    3. opt = b         optarg = 200            optind = 4              argv[optind] = -c  
    4. opt = c         optarg = 300            optind = 6              argv[optind] = -d  
    5. opt = d         optarg = (null)         optind = 7              argv[optind] = (null)  

    2、输入选项参数错误的情况

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./opt -a 100 -b 200 -c 300 -d  
    2. opt = a         optarg = (null)         optind = 2              argv[optind] = 100  
    3. opt = b         optarg = 200            optind = 5              argv[optind] = -c  
    4. opt = c         optarg = 300            optind = 7              argv[optind] = -d  
    5. opt = d         optarg = (null)         optind = 8              argv[optind] = (null)  

    导致解析错误,第一个optarg = null,实际输入参数100,由于格式不正确造成的(可选参数格式固定)

    参数丢失,也会导致错误,c选项是必须有参数的,不加参数提示错误如下:

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./opt -a -b 200 -c        
    2. opt = a         optarg = (null)         optind = 2              argv[optind] = -b  
    3. opt = b         optarg = 200            optind = 4              argv[optind] = -c  
    4. ./opt: optionrequires an argument -- 'c'  
    5. opt = ?         optarg = (null)         optind = 5              argv[optind] = (null)  

    这种情况,optstring中第一个字母不是’:’,如果在optstring中第一个字母加’:’,则最后丢失参数的那个选项opt返回的是’:’,不是’?’,并且没有提示错误信息,这里不再列出。

    命令行选项未定义,-e选项未在optstring中定义,会报错:

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./opt -a -b 200 -e  
    2. opt = a         optarg = (null)         optind = 2              argv[optind] = -b  
    3. opt = b         optarg = 200             optind = 4              argv[optind] = -e  
    4. ./opt: invalidoption -- 'e'  
    5. opt = ?         optarg = (null)         optind = 5              argv[optind] = (null)  

    到这里应该已经把getopt函数的功能讲解清楚了吧,下边来说说getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定“长参数”(或者说长选项),与getopt函数对比,getopt_long比其多了两个参数:

    (2) getopt_long函数

    定义:int getopt_long(int argc, char * const argv[], const char *optstring,

                                     const struct option *longopts,int *longindex);

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

    参数:longopts    指明了长参数的名称和属性

                longindex   如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值

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

    [cpp] view plain copy
     
    1. <span style="font-size:14px;">struct option {</span>  
    2. const char  *name;       /* 参数名称 */  
    3. int          has_arg;    /* 指明是否带有参数 */  
    4. int          *flag;      /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */  
    5. int          val;        /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */  
    6. };  

    has_arg  指明是否带参数值,其数值可选:

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

    接着看一下实例操作会更加深刻地理解:

    实例

    [cpp] view plain copy
     
    1. int main(intargc, char *argv[])  
    2. {  
    3.     int opt;  
    4.     int digit_optind = 0;  
    5.     int option_index = 0;  
    6.     char *string = "a::b:c:d";  
    7.     static struct option long_options[] =  
    8.     {    
    9.         {"reqarg", required_argument,NULL, 'r'},  
    10.         {"optarg", optional_argument,NULL, 'o'},  
    11.         {"noarg",  no_argument,         NULL,'n'},  
    12.         {NULL,     0,                      NULL, 0},  
    13.     };   
    14.     while((opt =getopt_long_only(argc,argv,string,long_options,&option_index))!= -1)  
    15.     {    
    16.         printf("opt = %c ", opt);  
    17.         printf("optarg = %s ",optarg);  
    18.         printf("optind = %d ",optind);  
    19.         printf("argv[optind] =%s ", argv[optind]);  
    20.         printf("option_index = %d ",option_index);  
    21.     }    
    22. }  

    编译上述程序并执行结果:

    1、正确输入长选项的情况

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./long --reqarg 100 --optarg=200 --noarg  
    2. opt = r optarg =100     optind = 3   argv[optind] = --optarg=200  option_index = 0  
    3. opt = o optarg =200     optind = 4   argv[optind] = --noarg        option_index = 1  
    4. opt = n optarg =(null) optind = 5    argv[optind] =(null)          option_index = 2  

    或者这种方式:

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./long –reqarg=100 --optarg=200 --noarg  
    2. opt = r optarg =100     optind = 2   argv[optind] = --optarg=200  option_index = 0  
    3. opt = o optarg =200     optind = 3   argv[optind] = --noarg        option_index = 1  
    4. opt = n optarg =(null) optind = 4    argv[optind] =(null)          option_index = 2  

    可选选项可以不给参数

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./long --reqarg 100 --optarg --noarg     
    2. opt = r optarg =100     optind = 3     argv[optind] = --optarg option_index = 0  
    3. opt = o optarg =(null) optind = 4      argv[optind] =--noarg   option_index = 1  
    4. opt = n optarg =(null) optind = 5      argv[optind] =(null)     option_index = 2  

    2、输入长选项错误的情况

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./long --reqarg 100 --optarg 200 --noarg   
    2. opt = r optarg =100     optind = 3     argv[optind] = --optarg  option_index= 0  
    3. opt = o optarg =(null) optind = 4      argv[optind] =200        option_index = 1  
    4. opt = n optarg =(null) optind = 6      argv[optind] =(null)     option_index = 2  

    这时,虽然没有报错,但是第二项中optarg参数没有正确解析出来(格式应该是—optarg=200)

    必须指定参数的选项,如果不给参数,同样解析错误如下:

    [cpp] view plain copy
     
    1. dzlab:~/test/test#./long --reqarg --optarg=200 --noarg      
    2. opt = r optarg =--optarg=200  optind = 3 argv[optind] =--noarg  option_index = 0  
    3. opt = n optarg =(null)         optind = 4 argv[optind] =(null)    option_index = 2  

    长选项的举例说明暂且就这么多吧,其它如选项错误、缺参数、格式不正确的情况自己再试验一下。

    (3) getopt_long_only函数

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

  • 相关阅读:
    七、AOP统一处理以及日志打印
    六、spring Boot项目表单验证(最小值为例)以及spring的常用注解
    五、spring-data-Jpa 数据库操作
    四、spring Boot项目中Controller的使用
    三、SpringBoot的常用配置(.yml通过配置文件和注解进行属性注入,以及分别配置生产、开发环境)
    机器学习中的 上采样 下采样 过采样 欠采样
    Mac 安装/卸载 brew
    Keras 训练自己的人脸特征点提取模型的坑
    Keras 使用自己编写的数据生成器
    iPhone 设备管理在哪(已解决)
  • 原文地址:https://www.cnblogs.com/xiaofeiIDO/p/6688659.html
Copyright © 2011-2022 走看看