C++实现的命令行参数管理


在用C++编写可运行程序时,经常需要输入除了可运行文件之外的其它的命令行参数,可以用传统的getopt函数来分析,本文基于面向对象,分析一种管理命令行参数方法 -- 来源于webrtc项目,在阅读过程中,大家分享一下。

一,传统命令行分析

包含头文件:

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

二,命令行参数管理

假设命令行的输入格式的规则如下:

  • --flag          布尔类型。
  • --noflag      布尔类型。
  • --flag=value  等号周边没有空格。

2.1 参数的值封装---FlagValue

这个类对参数的值进行封装,如--prefix=/usr,作为一个命令行参数时,prefix为键,/usr为值。在参数中,在此定义值的类型为布尔、整型、浮点、字符串中的一种。

由于一个值在只能取四种的一种,所以此处用联合类型表示FlagValue。

  1. union FlagValue { 
  2.   static FlagValue New_BOOL(int b) { 
  3.     FlagValue v; 
  4.     v.b = (b != 0); 
  5.     return v; 
  6.   } 
  7.  
  8.   static FlagValue New_INT(int i) { 
  9.     FlagValue v; 
  10.     v.i = i; 
  11.     return v; 
  12.   } 
  13.  
  14.   static FlagValue New_FLOAT(float f) { 
  15.     FlagValue v; 
  16.     v.f = f; 
  17.     return v; 
  18.   } 
  19.  
  20.   static FlagValue New_STRING(const char* s) { 
  21.     FlagValue v; 
  22.     v.s = s; 
  23.     return v; 
  24.   } 
  25.  
  26.   bool b; 
  27.   int i; 
  28.   double f; 
  29.   const char* s; 
  30. }; 

这个联合类型对命令行中键值对中的值进行封装,可以表示四种类型。

2.2 命令行中键值的表示 -- Flag

这个类是表示一对键值的抽象,包含下列元素:

  • 键值对。包括name和variable_表示键和值。如--prefix=/usr中,name的值为prefix,variable_为/usr的一个表示。
  • 链表维护域。Flag *next_用于指向下一个命令行参数。
  • comment_表示该参数的解释。
  • file表示和键值相关的外部文件。
  • default_表示默认情况下,就是用户没有输入该参数的情况下默认的值。
  • 定义友元类FlagList,因为FlagList需要访问Flag的next_域。
  1. class Flag { 
  2.  public
  3.   enum Type { BOOLINTFLOAT, STRING }; 
  4.  
  5.   // Internal use only.  
  6.   Flag(const char* file, const char* name, const char* comment, 
  7.        Type type, void* variable, FlagValue default_); 
  8.  
  9.   // General flag information  
  10.   const char* file() const  { return file_; } 
  11.   const char* name() const  { return name_; } 
  12.   const char* comment() const  { return comment_; } 
  13.  
  14.   // Flag type  
  15.   Type type() const  { return type_; } 
  16.  
  17.   // Flag variables  
  18.   bool* bool_variable() const { 
  19.     assert(type_ == BOOL); 
  20.     return &variable_->b; 
  21.   } 
  22.    
  23.   int* int_variable() const { 
  24.     assert(type_ == INT); 
  25.     return &variable_->i; 
  26.   } 
  27.    
  28.   double* float_variable() const { 
  29.     assert(type_ == FLOAT); 
  30.     return &variable_->f; 
  31.   } 
  32.    
  33.   const char** string_variable() const { 
  34.     assert(type_ == STRING); 
  35.     return &variable_->s; 
  36.   } 
  37.  
  38.   // Default values  
  39.   bool bool_default() const { 
  40.     assert(type_ == BOOL); 
  41.     return default_.b; 
  42.   } 
  43.    
  44.   int int_default() const { 
  45.     assert(type_ == INT); 
  46.     return default_.i; 
  47.   } 
  48.    
  49.   double float_default() const { 
  50.     assert(type_ == FLOAT); 
  51.     return default_.f; 
  52.   } 
  53.    
  54.   const char* string_default() const { 
  55.     assert(type_ == STRING); 
  56.     return default_.s; 
  57.   } 
  58.  
  59.   // Resets a flag to its default value  
  60.   void SetToDefault(); 
  61.  
  62.   // Iteration support  
  63.   Flag* next() const  { return next_; } 
  64.  
  65.   // Prints flag information. The current flag value is only printed  
  66.   // if print_current_value is set.  
  67.   void Print(bool print_current_value); 
  68.  
  69.  private
  70.   const char* file_; 
  71.   const char* name_; 
  72.   const char* comment_; 
  73.  
  74.   Type type_; 
  75.   FlagValue* variable_; 
  76.   FlagValue default_; 
  77.  
  78.   Flag* next_; 
  79.  
  80.   friend class FlagList;  // accesses next_  
  81. }; 
  • 1
  • 2
  • 3
  • 下一页

相关内容