一个命令行参数解析器

因工作需要写一个console工具程序,运行参数很多,记得linux下有一个系统函数getopt可以很好得帮助程序员解析命令行参数,但是在VC中没有这个函数,研究了下linux中对该函数的帮助信息和头文件getopt.h,重新实现了getopt和getopt_long这两个函数,因为没有读过linux下getopt这个函数的源代码,所以这个函数肯定不够完善,不过经过试用,还是能够满足我个人需求的,这里把源代码贴出来,也请熟悉或者读过getopt源代码的朋友指正。 GetOpt.h
[csharp]  view plain copy
  1. /****************************************************************************** 
  2.  
  3.  
  4.  
  5. *   Filename:           GetOpt.h 
  6.  
  7.  
  8.  
  9. *   Description:       命令行参数解析器  
  10.  
  11.  
  12.  
  13. *   Date:              2008-06-19 
  14.  
  15.  
  16.  
  17. *   Author:            常海龙          (Email:[email protected] 
  18.  
  19. * 
  20.  
  21. *                             Copyright (c) 2008 常海龙 
  22.  
  23.  
  24.  
  25. *******************************************************************************/   
  26.  
  27.  
  28.  
  29.  
  30.  
  31. #ifdef __cplusplus  
  32.   
  33. extern"C" {  
  34.  
  35. #endif  
  36.   
  37.   
  38.   
  39. extern int optind;               //再次再次调用 getopt() 时的下一个 argv 指针的索引  
  40.   
  41. extern int optopt;              //最后一个已知选项  
  42.   
  43. extern char* optarg;         //指向当前选项参数(如果有)的指针  
  44.   
  45.   
  46.   
  47. extern int getopt( int argc, char *const argv[], const char *shortopts);  
  48.  
  49.  
  50.  
  51. #ifdef __cplusplus  
  52.   
  53. }  
  54.  
  55. #endif  
  56.  
  57.  
  58.  
  59. #ifdef __cplusplus  
  60.   
  61. extern"C" {  
  62.  
  63. #endif  
  64.   
  65.   
  66.   
  67. struct option   
  68.   
  69. {  
  70.   
  71.     char *name;                 //指向长选项名称的指针     
  72.   
  73.     int has_arg;                 //表示选项是否有参数  
  74.   
  75.     int *flag;                 
  76.   
  77.     int val;                        //表示选项的短参数  
  78.   
  79. };  
  80.   
  81.   
  82.   
  83. extern int getopt_long (int argc, char *const argv[],  
  84.   
  85.                         const char *shortopts, const struct option *longopts,   
  86.   
  87.                         int *longind);  
  88.  
  89.  
  90.  
  91. #ifdef __cplusplus  
  92.   
  93. }  
  94.  
  95. #endif  
  96.  
  97.  
  98.  
  99.  
  100.  
  101. #define     no_argument         0  
  102.  
  103. #define     required_argument   1  
  104.  
  105. #define     optional_argument   2  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113. #define CASE_SENSITIVE      //定义参数处理器是否大小写敏感<span style="font-family: Arial,Verdana,Sans-Serif;">  
  114. </span>  
GetOpt.c
[csharp]  view plain copy
  1. /****************************************************************************** 
  2.  
  3.  
  4.  
  5. *   Filename:       GetOpt.c  
  6.  
  7.  
  8.  
  9. *   Description:    命令行参数解析器  
  10.  
  11.  
  12.  
  13. *   Date:                  2008-06-19 
  14.  
  15.  
  16.  
  17. *   Author:               常海龙      (Email:[email protected] 
  18.  
  19. * 
  20.  
  21. *                    Copyright (c) 2008 常海龙 
  22.  
  23.  
  24.  
  25. *******************************************************************************/   
  26.  
  27.  
  28.  
  29. #include"GetOpt.h"  
  30.  
  31. #include"string.h"  
  32.   
  33.   
  34.   
  35. int optind = 1;             //即将进行扫描的参数在argv[]中的索引  
  36.   
  37.   
  38.   
  39. //存放解析后返回值如果某一个argument无效,返回'?',该值存放argument  
  40.   
  41. int optopt;                   
  42.   
  43.   
  44.   
  45. char* optarg;               //如果当前参数有后续参数,该值指向这个后续参数  
  46.   
  47.   
  48.   
  49. ///////////////////////////////////////////////////////////////////////////////  
  50.   
  51.   
  52.   
  53. int paser_shotops(int argc,char *const argv[],  
  54.   
  55.                   size_t length,                //欲解析的argument项的长度  
  56.   
  57.                   char *item_cont,              //存放欲解析的argument  
  58.   
  59.                   const char *shortopts           
  60.   
  61.                   )  
  62.   
  63. {  
  64.   
  65.     char *pos = NULL;                             
  66.   
  67.   
  68.   
  69.     if(length == 2 && item_cont[0] == '-')      //如果符合  -h  这样的条件就可进行解析  
  70.   
  71.     {  
  72.   
  73.         pos = strchr(shortopts,item_cont[1]);   //当前argument在shortopts中出现的起始位置  
  74.   
  75.   
  76.   
  77.         if(NULL == pos)  
  78.   
  79.         {  
  80.   
  81.             optind++;                           //如果在shortopts中找不到,则返回'?'  
  82.   
  83.             optopt = item_cont[1];  
  84.   
  85.             return '?';  
  86.   
  87.         }  
  88.   
  89.         else  
  90.   
  91.         {  
  92.   
  93.             if(*(++pos) == ':')                 //如果该项带有后续参数,用optarg存储  
  94.   
  95.                 optarg = argv[++optind];  
  96.   
  97.   
  98.   
  99.             optind++;  
  100.   
  101.             return item_cont[1];  
  102.   
  103.         }     
  104.   
  105.     }  
  106.   
  107.     else                                        //如果不符合解析的条件,返回'?'  
  108.   
  109.     {  
  110.   
  111.         optopt = item_cont[0];  
  112.   
  113.         optind = argc;  
  114.   
  115.         return '?';  
  116.   
  117.     }  
  118.   
  119. }  
  120.   
  121.   
  122.   
  123. ///////////////////////////////////////////////////////////////////////////////  
  124.   
  125.   
  126.   
  127. int paser_longopts(int argc, char *const argv[],  
  128.   
  129.                    size_t length,                   //欲解析的argument项的长度  
  130.   
  131.                    char *item_cont,             //存放欲解析的argument  
  132.   
  133.                    const char *shortopts,  
  134.   
  135.                    const struct option *longopts  
  136.   
  137.                    )  
  138.   
  139. {  
  140.   
  141.     char *assist_arg = NULL;                          //辅助字符串  
  142.   
  143.   
  144.   
  145.     int long_index = 0;                                        //longopts的索引  
  146.   
  147.   
  148.   
  149.     //如果欲解析的argument长度大于2,并且第一,二个字符都是'-'  
  150.   
  151.     if( (length > 2) && (item_cont[0] == '-') && (item_cont[1] == '-'))  
  152.   
  153.     {  
  154.   
  155.   
  156.   
  157.         //循环longopts,查找和当前参数匹配的项目  
  158.   
  159.         while(longopts[long_index].name != NULL)  
  160.   
  161.         {  
  162.   
  163.             if(strcmp(item_cont+2,longopts[long_index].name) == 0)  
  164.   
  165.             {  
  166.   
  167.                 if(longopts[long_index].has_arg == required_argument)  
  168.   
  169.                     optarg = argv[++optind];  
  170.   
  171.   
  172.   
  173.                 if(longopts[long_index].has_arg == optional_argument)  
  174.   
  175.                 {  
  176.   
  177.                     //因为是可选后续参数,首先取得后续参数,然后判断  
  178.   
  179.                     assist_arg = argv[optind + 1];  
  180.   
  181.   
  182.   
  183.                     if(assist_arg[0] != '-')  
  184.   
  185.                     {  
  186.   
  187.                         optarg = assist_arg;  
  188.   
  189.                         ++optind;  
  190.   
  191.                     }  
  192.   
  193.                 }  
  194.   
  195.   
  196.   
  197.                 //在longopts中找到匹配项后,返回val值  
  198.   
  199.                 optopt = longopts[long_index].val;  
  200.   
  201.                 optind++;  
  202.   
  203.   
  204.   
  205.                 return optopt;  
  206.   
  207.             }  
  208.   
  209.             else  
  210.   
  211.                 long_index++;  
  212.   
  213.         }  
  214.   
  215.         //如果在longopts中没有匹配项,则进行提示并继续解析后面的参数  
  216.   
  217.         optopt = item_cont[2];  
  218.   
  219.         ++optind;  
  220.   
  221.         return '?';  
  222.   
  223.     }  
  224.   
  225.     else   
  226.   
  227.         //对短参数项进行解析  
  228.   
  229.         return paser_shotops(argc,argv,length,item_cont,shortopts);  
  230.   
  231. }  
  232.   
  233.   
  234.   
  235. ///////////////////////////////////////////////////////////////////////////////  
  236.   
  237.   
  238.   
  239. int getopt( int argc, char *const argv[], const char *shortopts )  
  240.   
  241. {     
  242.   
  243.   
  244.   
  245.     char *arg_item = NULL;  
  246.   
  247.   
  248.   
  249.     size_t len = 0;  
  250.   
  251.   
  252.   
  253.     if(argc == 1)  
  254.   
  255.         return -1;  
  256.   
  257.     else  
  258.   
  259.     {  
  260.   
  261.         for(; optind < argc; optind++)  
  262.   
  263.         {  
  264.   
  265.             arg_item = argv[optind];  
  266.   
  267.   
  268.   
  269.             len = strlen(arg_item);  
  270.  
  271.  
  272.  
  273. #ifndef CASE_SENSITIVE  
  274.   
  275.   
  276.   
  277.             arg_item = strlwr(arg_item);  
  278.  
  279.  
  280.  
  281. #endif  
  282.   
  283.             return paser_shotops(argc,argv,len,arg_item,shortopts);  
  284.   
  285.   
  286.   
  287.         }  
  288.   
  289.   
  290.   
  291.         optind = 1;                   //如果解析完毕,在最后将optind重置为1  
  292.   
  293.         return -1;  
  294.   
  295.     }  
  296.   
  297. }  
  298.   
  299.   
  300.   
  301. ///////////////////////////////////////////////////////////////////////////////  
  302.   
  303.   
  304.   
  305. int getopt_long (int argc, char *const argv[],  
  306.   
  307.                  const char *shortopts, const struct option *longopts,   
  308.   
  309.                  int *longind)  
  310.   
  311. {  
  312.   
  313.     char *pos = NULL;  
  314.   
  315.   
  316.   
  317.     char *arg_item = NULL;  
  318.   
  319.   
  320.   
  321.     size_t len = 0;  
  322.   
  323.   
  324.   
  325.     if(argc == 1)  
  326.   
  327.         return -1;  
  328.   
  329.     else  
  330.   
  331.     {  
  332.   
  333.         for(; optind < argc; optind++)  
  334.   
  335.         {  
  336.   
  337.             arg_item = argv[optind];  
  338.   
  339.   
  340.   
  341.             len = strlen(arg_item);  
  342.  
  343.  
  344.  
  345. #ifndef CASE_SENSITIVE  
  346.   
  347.               
  348.   
  349.             arg_item = strlwr(arg_item);  
  350.  
  351.  
  352.  
  353. #endif  
  354.   
  355.                         //在与解析的参数项后面加0,方便字符串的操作  
  356.   
  357.             *(arg_item+len) = 0;  
  358.   
  359.   
  360.   
  361.             return paser_longopts(argc,argv,len,arg_item,shortopts,longopts);  
  362.   
  363.   
  364.   
  365.         }  
  366.   
  367.   
  368.   
  369.             optind = 1;                     //如果解析完毕,在最后将optind重置为1  
  370.   
  371.         return -1;  
  372.   
  373.     }  
  374.   
  375. }  
  376.   
  377.   
  378.   
  379. ///////////////////////////////////////////////////////////////////////////////  

你可能感兴趣的:(一个命令行参数解析器)