zoukankan      html  css  js  c++  java
  • getopt函数

    getopt -- 解析命令的可选项
     
    【说明】getopt只是一个简单的解析命令可选项的函数,只能进行简单的格式命令解析,格式如下:
     
    1、形如:cmd [-a][-b] //对短选项的解析;
    2、形如:cmd [-a a_argument][-b b_argument] //对短选项及短选项的参数解析;
    3、形如:cmd [-a[a_argument]] //选项a的参数也是可选的情况解析
     
    原型:
     
    #include <unistd.h>
     
    extern char *optarg;
    extern int optind, opterr, optopt;
    int getopt(int argc, char * const argv[], const char *optstring);
     
    描述:
     
    1、getopt函数解析命令行参数,argcargv是调用main函数时传入的参数。传入的'-'开始的字符被解析为选项,getopt一次执行解析出一个option,如果循环执行,可以将argv中的全部option解析出来;
    2、在getopt的执行中,每次进入都会更新optind变量,该变量指向下一个argv参数;
    3、如getopt返回-1,表示argv[]中的所有选项被解析出,optind指向第一个非选项的argument元素;这里要注意,在getopt执行过程中会将单独的argument交换到argv数组的后面,option选项提前,如:cmd -a file1 -b file2,如果a/b均为不带参数的选项,这最终argv数组变为:cmd -a -b file1 file2;
    4、optstring指定选项合法的选项,一个字符代表一个选项,在字符后面加一个':'表示该选项带一个参数,字符后带两个':'表示该选项带可选参数(参数可有可无),若有参数,optarg指向该该参数,否则optarg为0;
    5、前面说了getopt会进行argv顺序的调整,但也可以通过设置optstring改变它的方式,这里有两种:
         1) 如果optstring的第一个参数是'+'或者POSIXLY_CORRECT被设置,则getopt在原argv的顺序上遇到第一个非选项就返回-1;
         2) 如果optstring的第一个参数是'-',则会将所有的非选项当选项处理,并且返回1,用字符代码1表示该选项;
    6、如果getopt不能识别一个选项字符,它会打印一个错误消息到stderr上,并将该字符存放到optopt中,返回'?';调用程序可以设置opterr=0设置不打印错误信息;注意:要使能打印错误信息,optstring的第一个字符(或者在第一个字符是+/-之后)不能是':',否则也不会打印错误;
    7、如果optstring中指定了option需要参数,但在命令行没有参数,那么getopt将返回'?',如果在optstring的第一个字符(或者在第一个字符是+/-之后)是':',那么将返回':';
     
    返回值:
     
    1、返回类型为int,这个在编程的时候要注意,因为返回值类型范围要包含-1,很容易返回值接收定义为char,但在一些系统中char是无符号的,将导致程序错误;
    2、当传入的argv中的选项全部被解析,getopt()返回-1,这也是getopt进行选项解析的循环截至条件;
    3、如果argv中解析出optstring中描述的选项字符,则返回该字符,如果该选项指定了参数,则全局变量optarg指向该参数;
    4、如果getopt遇到一个非optstring指定的选项字符,这表示该选项是未识别的,返回'?',并且将该选项存放到全局变量optopt中;
    5、如果optstring指定了选项必须带参数,但传入的相应option丢失了参数,返回值依赖于optstring的第一个字符,若第一个字符是':',返回':',否则返回'?';由于非法的选项返回也是'?',所以常常optstring的第一个字符指定为':';同时将该选项存放到全局变量 optopt中;
     
    测试例程:
     
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <string.h>
     5 #include <sys/types.h>
     6  
     7 int main(int argc, char *argv[])
     8 {   
     9         extern char *optarg;
    10         extern int optind, opterr, optopt;
    11         int i;
    12         int ret;
    13  
    14         for (i=0; i<argc; i++)
    15         {   
    16                 printf ("argv[%d] %s
    ", i, argv[i]);
    17         }   
    18         printf ("
    ");
    19  
    20         while ((ret = getopt(argc, argv, ":a:b::c")) != -1)
    21         {   
    22                 switch (ret) {
    23                 case 'a':
    24                         printf ("option: %c argv: %s
    ", ret, optarg);
    25                         break;
    26                 case 'b':
    27                         if (optarg)
    28                                 printf ("option: %c argv: %s
    ", ret, optarg);
    29                         else
    30                                 printf ("option: %c no argument
    ", ret);
    31                         break;
    32                 case '?':
    33                         printf ("encountered a unrecognized option: %c, argv: %s
    ", optopt, argv[optind - 1]);
    34                         break;
    35                 case ':':
    36                         printf ("option: %c missing argument
    ", optopt);
    37                         break;
    38                 default:
    39                         printf ("option: %c
    ", ret);
    40                         break;
    41                 }   
    42         }
    43  
    44         printf ("
    optind: %d
    
    ", optind);
    45         for (i=optind; i>0 && i<argc; i++)
    46                 printf ("argv[%d] %s
    ", i, argv[i]);
    47  
    48         printf ("
    ");
    49         for (i=0; i<argc; i++)
    50                 printf ("argv[%d] %s
    ", i, argv[i]);
    51  
    52         return 0;
    53 }
    然后我们运行测试例程,自己根据前面的描述进行一些分析:
     
    root@ParseCmdLine:./parse_cmdline -axxx -byyy
    argv[0] ./parse_cmdline
    argv[1] -axxx
    argv[2] -byyy
     
    option: a argv: xxx
    option: b argv: yyy
     
    optind: 3
     
     
    argv[0] ./parse_cmdline
    argv[1] -axxx
    argv[2] -byyy
     
    root@ParseCmdLine:./parse_cmdline -a xxx -b yyy
    argv[0] ./parse_cmdline
    argv[1] -a
    argv[2] xxx
    argv[3] -b
    argv[4] yyy
     
    option: a argv: xxx
    option: b no argument
     
    optind: 4
     
    argv[4] yyy
     
    argv[0] ./parse_cmdline
    argv[1] -a
    argv[2] xxx
    argv[3] -b
    argv[4] yyy
    从这个可以看出,带参数的option参数可以紧跟,也可以中间有空格;
     
    root@ParseCmdLine:./parse_cmdline -axxx -b yyy -c
    argv[0] ./parse_cmdline
    argv[1] -axxx
    argv[2] -b
    argv[3] yyy
    argv[4] -c
     
    option: a argv: xxx
    option: b no argument
    option: c
     
    optind: 4
     
    argv[4] yyy
     
    argv[0] ./parse_cmdline
    argv[1] -axxx
    argv[2] -b
    argv[3] -c
    argv[4] yyy
     
    root@ParseCmdLine:./parse_cmdline -axxx -byyy -c
    argv[0] ./parse_cmdline
    argv[1] -axxx
    argv[2] -byyy
    argv[3] -c
     
    option: a argv: xxx
    option: b argv: yyy
    option: c
     
    optind: 4
     
     
    argv[0] ./parse_cmdline
    argv[1] -axxx
    argv[2] -byyy
    argv[3] -c
    从这里可以看出,对于-b是可跟参数也可不跟参数的,参数必须紧跟,中间不能有空格。同时还可以看出:在有argument在argv中,最后出现了argv[]元素位置变化,选项前移了,而参数后移
     
    root@ParseCmdLine:./parse_cmdline -x
    argv[0] ./parse_cmdline
    argv[1] -x
     
    encountered a unrecognized option: x, argv: -x
     
    optind: 2
     
     
    argv[0] ./parse_cmdline
    argv[1] -x
     
    root@ParseCmdLine:./parse_cmdline -a
    argv[0] ./parse_cmdline
    argv[1] -a
     
    option: a missing argument
     
    optind: 2
     
     
    argv[0] ./parse_cmdline
    argv[1] -a
    这里可以看出未识别的option,和丢失参数的option情况;
     
    // 修改代码while ((ret = getopt(argc, argv, "a:b::c")) != -1)
    root@ParseCmdLine:./parse_cmdline -x                   
    argv[0] ./parse_cmdline
    argv[1] -x
     
    ./parse_cmdline: invalid option -- x
    encountered a unrecognized option: x, argv: -x
     
    optind: 2
     
     
    argv[0] ./parse_cmdline
    argv[1] -x
     
    // 修改代码while ((ret = getopt(argc, argv, "+a:b::c")) != -1)
    root@ParseCmdLine:./parse_cmdline -x xxxx -ayyyy -bzzz kkkk
    argv[0] ./parse_cmdline
    argv[1] -x
    argv[2] xxxx
    argv[3] -ayyyy
    argv[4] -bzzz
    argv[5] kkkk
     
    ./parse_cmdline: invalid option -- x
    encountered a unrecognized option: x, argv: -x
    option: a argv: yyyy
    option: b argv: zzz
     
    optind: 4
     
    argv[4] xxxx
    argv[5] kkkk
     
    argv[0] ./parse_cmdline
    argv[1] -x
    argv[2] -ayyyy
    argv[3] -bzzz
    argv[4] xxxx
    argv[5] kkkk
    这块代码说明了optstring第一个字符的作用,剩余的其他功能读者自己分析;
  • 相关阅读:
    javaScript系列 [35]HTML页面渲染的基本过程
    javaScript系列 [29] RegExp
    javaScript系列 [40]defineProperty
    javaScript系列 [32] type
    javaScript系列 [34]FormData
    javaScript系列 [39]deepClone
    javaScript系列 [33] new
    javaScript系列 [36]Call by sharing
    javaScript系列 [38]浏览器、HTML和内核(引擎)
    javaScript系列 [28] Event
  • 原文地址:https://www.cnblogs.com/water-moon/p/5983139.html
Copyright © 2011-2022 走看看