linux系统getopt函数详解

时间:2021-02-09 04:35:48

getopt()函数就是用来解析命令行参数

调用形式一般如下:
  1. while((= getopt(argc, argv, "xy:z::")) != -1){
  2.       switch(c){
  3.       case 'x':   ... ...
  4.       case 'y':   ... ...
  5.       case 'z':   ... ...
  6.       ... ....
  7.       }
  8. }
  9. .
getopt函数的原型如下:
  1. #include <unistd.h>
  2. int getopt(int argc, char * const argv[], const char *optstring);
  3. extern char *optarg; 
    extern 
    int optind,  // 初始化值为1,下一次调用getopt时,从optind存储的位置重新开始检查选项。 
    extern int opterr,  // 初始化值为1,当opterr=0时,getopt不向stderr输出错误信息。
    extern int optopt;  // 当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,
                                        
    // 该选项存储在optopt中, getopt返回'?’。
getopt()函数用于解析命令行参数。
optarg和optind是两个最重要的external 变量。optarg是指向参数的指针(当然这只针对有参数的选项);optind是argv[]数组的索引,众所周知,argv[0]是函数名称,所有参数从argv[1]开始,所以optind被初始化设置指为1。       每调用一次getopt()函数,返回一个选项,如果该选项有参数,则optarg指向该参数。 在命令行选项参数再也检查不到optstring中包含的选项时,返回-1。
字符串optstring,它是作为选项的字符串的列表。
函数getopt()认为optstring中,以'-’开头的字符(注意!不是字符串!!)就是命令行参数选项,有的参数选项后面可以跟参数值。optstring中的格式规范如下:
1) 单个字符,表示选项,
2) 单个字符后接一个冒号”:”,表示该选项后必须跟一个参数值。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
3) 单个字符后跟两个冒号”::”,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。
getopt()函数的第三个参数optstring是一个有所有合法的“可选字符”所组成的字符串。《1》在参数optstring的“可选字符”如果后面带有一个':',则表示在该“可选字符”的后面必须有一个参数比如“o:"表示: gcc -o arg 在-o的后面必须带有一个参数arg. 在getopt()函数解析完"o:"对应的命令行参数时,char型的指针optarg则指向了参数"arg"《2》如果在“可选字符”的后面带有了两个':'时,则表示在该“可选字符”后面可能有也可能没有参数,有参数,则optarg指向参数,没有则为0。这是GNU的一个关于getopt()函数的扩展。《3》如果optstring中含有一个大写的'W'字符,后面带有一个冒号,也就是形如"W:",则表示该“可选字符”是一个“长选项”,也就是说不是只有一个字符的“可选字符”。比如:gcc -Wall  hello.c 要解析该命令行,getopt()函数中的第三个参数optstring应该是:"W:all",而且当解析到“-Wall"时optarg = "all".  这一点也是GNU对getopt()函数的扩展。《4》如果getopt()函数在argv中解析到一个没有包含在optstring中的“可选字符”,它会打印一个错误信息,并将该“可选字符”保存在optopt中,并返回字符'?'。当然,我们可以将变量opterr赋值为0,来阻止getopt()函数输出错误信息《5》当getopt()函数的第三个参数optstring的第一个字符是':'时,很显然,这是由于少写了一个"可选字符"的缘故。此时,getopt()函数不返回'?',而是返回':'来暗示我们漏掉了一个”可选字符”.
  1. [cpp] view plain copy
    1. <span style="font-size:14px;">#include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <unistd.h>  
    4. #include <fcntl.h>  
    5. int main(int argc, char *argv[])  
    6. {  
    7.         int c;  
    8.         opterr = 0;   
    9.         while((c = getopt(argc, argv, "Oo:W:all")) != -1){  
    10.                 printf("option char: %c\n", c);  
    11.                 switch(c){  
    12.                 case 'O':  
    13.                         printf("optimization flag is open.\n\n");  
    14.                         break;  
    15.                 case 'o':  
    16.                         printf("the obj is: %s\n\n", optarg);  
    17.                         break;  
    18.                 case 'W':  
    19.                         printf("optarg: %s\n\n", optarg);  
    20.                         break;          
    21.                 case '?':  
    22.                         fprintf(stderr, "Usage: %s [-Wall] [-O] [-o arg] arg\n", argv[0]);  
    23.                         break;  
    24.                 case ':':  
    25.                         fprintf(stderr, "miss option char in optstring.\n");  
    26.                         break;  
    27.                 }  
    28.         }  
    29.         exit(0);  
    30. }</span>  
    编译:gcc -Wall -o mygcc gcc.c运行:./mygcc -Wall -O -o mygcc结果:option char: Woptarg: all
    option char: Ooptimization flag is open.
    option char: othe obj is: mygcc[cpp] view plain copy
    1. <span style="font-size:14px;">#include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <unistd.h>  
    4. #include <fcntl.h>  
    5. int main(int argc, char *argv[])  
    6. {  
    7.         int c;  
    8.   
    9.         // opterr = 0;   
    10.         while((c = getopt(argc, argv, "iu:z:")) != -1){  
    11.               switch(c){  
    12.               case 'i':  
    13.                  printf("current option index:(optind-1)=%d, argv[optind-1]=argv[%d]=%s\n",  
    14.                                 (optind-1), (optind-1), argv[optind-1]);  
    15.                  printf("next option index:(optind)=%d, argv[optind]=argv[%d]=%s\n",  
    16.                                 (optind), (optind), argv[optind]);  
    17.                  printf("optarg=%s, opterr=%d, optopt=%d\n\n", optarg, opterr, optopt);  
    18.                  break;  
    19.   
    20.              case 'u':  
    21.                  printf("current option index:(optind-2)=%d, argv[optind-2]=argv[%d]=%s\n",  
    22.                                 (optind-2), (optind-2), argv[optind-2]);  
    23.                  printf("next option index:(optind)=%d, argv[optind]=argv[%d]=%s\n",  
    24.                                 (optind), (optind), argv[optind]);  
    25.                  printf("optarg=%s, opterr=%d, optopt=%d\n\n", optarg, opterr, optopt);  
    26.                  break;  
    27.   
    28.              case 'z':  
    29.                  printf("current option index:(optind-1)=%d, argv[optind-1]=argv[%d]=%s\n",  
    30.                                 (optind-1), (optind-1), argv[optind-1]);  
    31.                  printf("next option index:(optind)=%d, argv[optind]=argv[%d]=%s\n",  
    32.                                 (optind), (optind), argv[optind]);  
    33.                  printf("optarg=%s, opterr=%d, optopt=%d\n\n", optarg, opterr, optopt);  
    34.                  break;  
    35.   
    36.              case '?':  
    37.                  fprintf(stderr, "Usage: %s [-i] [-u username] [-z filename]\n", argv[0]);  
    38.                  break;  
    39.                 }  
    40.         }  
    41.         exit(0);  
    42. }</span>  
    编译:gcc -Wall -o getopt2 getopt2.c运行:./getopt2 -i -u username -z filename结果:current option index:(optind-1)=1, argv[optind-1]=argv[1]=-inext option index:(optind)=2, argv[optind]=argv[2]=-uoptarg=(null), opterr=1, optopt=0
    current option index:(optind-2)=2, argv[optind-2]=argv[2]=-unext option index:(optind)=4, argv[optind]=argv[4]=-zoptarg=username, opterr=1, optopt=0
    current option index:(optind-1)=5, argv[optind-1]=argv[5]=filenamenext option index:(optind)=6, argv[optind]=argv[6]=(null)optarg=filename, opterr=1, optopt=0