感谢支持
我们一直在努力

Linux选项-getopt/getopt_long

一、命令行简介


解释分析命令行通常是所以程序的第一个任务,C语言通过argc和argv参数来访问它的命令行参数。


最简单的命令行处理技术可以通过if判断来表示,如下例:



  1. if(argc>1 && argv[1][0] ==‘-‘ && argv[1][1] ==‘h’)  //判断命令行参数是否为-h   
  2. {   
  3.      do _ some thing();   
  4. }   

这样处理简单有序的命令行还可以,对于复杂的命令行处理显得有心无力,于是GNU提供两个函数专门用来处理命令行参数:


getopt 和getopt_long


二、getopt函数


getopt() 函数声明如下:



  1. #include <unistd.h>     
  2. int getopt(int argc, char *const argv[], const char *optstring);    
  3.      
  4. extern char *optarg;    
  5.    
  6. extern int optind, opterr, optopt;    

说 明:


函数的argc和argv参数通常直接从main()的参数直接传递而来。optstring是选项字母组成的字串。如果该字串里的任一字符后面有冒号,那么这个选项就要求有选项参数。


当给定getopt()命令参数的数量 (argc)、指向这些参数的数组 (argv) 和选项字串 (optstring) 后,getopt() 将返回第一个选项,并设置一些全局变量。使用相同的参数再次调用该函数时,它将返回下一个选项,并设置相应的全局变量。如果不再有可识别的选项,将返回 -1,此任务就完成了。


getopt()所设置的全家变量包括:


optarg —- 当前选项参数字符(如果有的话)


optind —- argv的当前索引值。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在
            argv[optind]至argv[argc-1]中可以找到。


optopt —- 用于当发现无效选项字符的时候,getopt函数或者返回 “?” 或者返回 “:” 字符,并且optopt包含了
            所发现的无效选项字符,或者当输入非法参数的时候,由optopt带回输入的非法参数(字符)


opterr —- 这个变量非零时,getopt()函数为“无效选项”和“缺少参数选项,并输出其错误信息。


另外:


如果optstring参数的第一个字符是冒号,那么getopt会根据错误情况返回不同的字符:


(1):当错误是无效选项,getopt返回 “?”


(2):当错误是缺少选项参数,getopt返回 “:”


(3): 无错误发生时,正常返回的是对应的字符!


注:GNU getopt()第三个特点是optstring中的选项字符后面接两个冒号,就允许该选项有可选的选项参数。在选项参数不存在的情况下,GNU getopt()返回选项字符并将optarg设置为NULL。


例子:



  1. #include<stdio.h>   
  2. #include<unistd.h>   
  3. #include<getopt.h>   
  4. /*the variables bellow was define in getopt.h 
  5. extern char *optarg;  
  6. extern int optind, opterr, optopt; 
  7. */  
  8. char* para = “:ab:c”;  
  9. void print_extern_val(void)  
  10. {  
  11.     printf(“optarg=%s.optind=%d.opterr=%d.optopt=%d=%c[END]/n”,  
  12.     optarg, optind, opterr, optopt, optopt);  
  13. }  
  14. int main(int argc,char* argv[])  
  15. {  
  16.       
  17.     int oc = -1;  
  18.       
  19.     char* b_input = NULL;  
  20.       
  21.     while((oc = getopt(argc,argv,para)) != -1)    
  22.     {         
  23.         switch(oc)        
  24.         {  
  25.               
  26.         case ‘a’:         
  27.             printf(“input para is a/n”);              
  28.             print_extern_val();  
  29.             break;  
  30.               
  31.         case ‘b’:     
  32.             b_input = optarg;         
  33.             printf(“input para is b,and optarg is %s/n”,b_input);     
  34.             print_extern_val();  
  35.             break;  
  36.               
  37.         case ‘c’:             
  38.             printf(“input para is c/n”);          
  39.             print_extern_val();  
  40.             break;  
  41.               
  42.         case ‘:’:             
  43.             printf(“option %c requires an argument/n”,optopt);    
  44.             print_extern_val();   
  45.             break;  
  46.               
  47.         case ‘?’:             
  48.         default:  
  49.             printf(“option %c is invalid:ignored/n”,optopt);  
  50.             print_extern_val();  
  51.             break;            
  52.         }         
  53.     }  
  54.       
  55.     return 0;     
  56. }   

结果:


     [root@localhost opts]# ./getopt -a 


     input para is a


     optarg=(null).optind=2.opterr=1.optopt=0=[END]


     [root@localhost opts]# ./getopt -a -b


     input para is a


     optarg=(null).optind=2.opterr=1.optopt=0=[END]


     option b requires an argument


     optarg=(null).optind=3.opterr=1.optopt=98=b[END]


     [root@localhost opts]# ./getopt -a -b mingming


     input para is a


     optarg=(null).optind=2.opterr=1.optopt=0=[END]


     input para is b,and optarg is mingming


     optarg=mingming.optind=4.opterr=1.optopt=0=[END]


     [root@localhost opts]# ./getopt -a -d


     input para is a


     optarg=(null).optind=2.opterr=1.optopt=0=[END]


     option d is invalid:ignored


     optarg=(null).optind=3.opterr=1.optopt=100=d[END]

三、getopt_long函数


getopt_long () 用来处理长选项,使用 man 3 getopt_long ,得到其声明如下:



  1. #include <getopt.h>     

  2. int getopt_long(int argc, char * const argv[], const char *optstring,     

  3. const struct option *longopts, int *longindex);    

  4. int getopt_long_only(int argc, char * const argv[], const char *optstring,     

  5. const struct option *longopts, int *longindex);   

前三个参数与getopt相同,下一个参数是指向数组的指针,这个数组是option结构数组,option结构称为长选项表,其声明如下:


 


struct  option  


{


    const char *name;


    int  has_arg;


    int  *flag;


    int  val;


 };   


 


结构中的元素解释如下:


const char *name :选项名,前面没有短横线


int  has_arg :描述长选项是否有参数,其值见下表













符号常量


数值


含义


no_argument


required_argument


optional_argument


0


1


2


选项没有参数


选项需要参数


选项参数是可选的


 


int  *flag


如果该指针为NULL,那么getopt_long返回val字段的值;


如果该指针不为NULL,那么会使得它所指向的结构填入val字段的值,同时getopt_long返回0 (*flag = val, then return)


如果flag不是 NULL,但未发现长选项,那么它所指向的变量的数值不变。


 
























返回值


含义


0


getopt_long() 设置一个标志,它的值与 option 结构中的 val 字段的值一样


1


每碰到一个命令行参数, optarg 都会记录它


‘?’


无效选项


‘:’


缺少选项参数


‘x’


选项字符 ‘x’


-1


选项解析结束



  1. #include<stdio.h>   

  2. #include<unistd.h>   

  3. #include<getopt.h>   

  4. /*the variables bellow was define in getopt.h 

  5. extern char *optarg;  

  6. extern int optind,  opterr,  optopt; 

  7. */  

  8. char* para = “:am:cf:v”;  

  9. int do_all = 0;  

  10. int do_help = 0;  

  11. int do_version = 0;  

  12. char* file = NULL;  

  13. void print_extern_val(void)  

  14. {  

  15.     printf(“optarg=%s.optind=%d.opterr=%d.optopt=%d=%c[END]/n”,   

  16.         optarg, optind, opterr, optopt, optopt);  

  17. }  

  18. /* 

  19. struct option  

  20. { 

  21.     const char *name; 

  22.     int has_arg; 

  23.     int *flag; 

  24.     int val; 

  25. }; 

  26. */  

  27. struct option longopt[]=  

  28. {  

  29.       

  30.     {“all”, no_argument, &do_all, 1},   

  31.           

  32.     {“file”, required_argument, NULL, ‘f’},   // val=’f’—> para中对应的选项  返回 ‘f’   

  33.       

  34.     {“help”, no_argument, &do_help, 1},           //返回 0 并置do_help = 1(1为对应的val)   

  35.       

  36.     {“version”, no_argument, &do_version, 1},   

  37.       

  38.     {“ming”, required_argument, NULL, ‘m’},   

  39.       

  40.     {0, 0, 0, 0},   //end flag   

  41.       

  42. };  

  43. int main(int argc, char* argv[])  

  44. {  

  45.       

  46.     int oc = -1;  

  47.       

  48.     char* m_input = NULL;  

  49.       

  50.     while((oc = getopt_long(argc, argv, para, longopt, NULL)) != -1)      

  51.     {  

  52.         printf(“getopt_long()return %d(%c)./n”, oc, oc);  

  53.         switch(oc)        

  54.         {  

  55.               

  56.         case ‘a’:             

  57.             printf(“input para is a/n”);  

  58.             print_extern_val();  

  59.             break;  

  60.               

  61.         case ‘m’:  

  62.             m_input = optarg;         

  63.             printf(“input para is m,and optarg is %s/n”,m_input);     

  64.             print_extern_val();       

  65.             break;  

  66.               

  67.         case ‘c’:             

  68.             printf(“input para is c/n”);  

  69.             print_extern_val();       

  70.             break;  

  71.               

  72.         case ‘v’:             

  73.             printf(“input para is v/n”);  

  74.             print_extern_val();       

  75.             break;  

  76.               

  77.         case ‘f’:             

  78.             printf(“input para is f/n”);              

  79.             file = “helloworld”;  

  80.             print_extern_val();       

  81.             break;  

  82.               

  83.         case 0:  

  84.             printf(“0-0-0-0-0-0-0-0/n”);      

  85.             print_extern_val();       

  86.             break;  

  87.               

  88.         case ‘:’:             

  89.             printf(“option %c requires an argument/n”, optopt);  

  90.             print_extern_val();       

  91.             break;  

  92.               

  93.         case ‘?’:             

  94.         default:          

  95.             printf(“option %d is invalid:ignored/n”, optopt);  

  96.             print_extern_val();       

  97.             break;            

  98.         }  

  99.           

  100.     }  

  101.       

  102.     printf(“do_all=%d/n”, do_all);    

  103.     printf(“do_help=%d/n”, do_help);  

  104.     printf(“do_version=%d/n”, do_version);  

  105.     printf(“do_file=%s/n”, file);  

  106.     printf(“m_input=%s/n”, m_input);  

  107.       

  108.     return 0;  

  109.       

  110. }   

结果:


     [root@localhost opts]# ./getopt_long –ming mayer


     getopt_long()return 109(m).


     input para is m,and optarg is mayer


     optarg=mayer.optind=3.opterr=1.optopt=0=[END]


     do_all=0


     do_help=0


     do_version=0


     do_file=(null)


     m_input=mayer


     [root@localhost opts]# ./getopt_long -m mayer   


     getopt_long()return 109(m).


     input para is m,and optarg is mayer


     optarg=mayer.optind=3.opterr=1.optopt=0=[END]


     do_all=0


     do_help=0


     do_version=0


     do_file=(null)


     m_input=mayer


     [root@localhost opts]# ./getopt_long -k


     getopt_long()return 63(?).


     option 107 is invalid:ignored


     optarg=(null).optind=2.opterr=1.optopt=107=k[END]


     do_all=0


     do_help=0


     do_version=0


     do_file=(null)


     m_input=(null)


     [root@localhost opts]# ./getopt_long –mayer


     getopt_long()return 63(?).


     option 0 is invalid:ignored


     optarg=(null).optind=2.opterr=1.optopt=0=[END]


     do_all=0


     do_help=0


     do_version=0


     do_file=(null)


     m_input=(null)


     [root@localhost opts]# ./getopt_long –ming


     getopt_long()return 58(:).


     option m requires an argument


     optarg=(null).optind=2.opterr=1.optopt=109=m[END]


     do_all=0


     do_help=0


     do_version=0


     do_file=(null)


     m_input=(null)


     [root@localhost opts]# ./getopt_long –all


     getopt_long()return 0().


     0-0-0-0-0-0-0-0


     optarg=(null).optind=2.opterr=1.optopt=0=[END]


     do_all=1


     do_help=0


     do_version=0


     do_file=(null)


     m_input=(null)

赞(0) 打赏
转载请注明出处:服务器评测 » Linux选项-getopt/getopt_long
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏