在用C++編寫可運行程序時,經常需要輸入除了可運行文件之外的其它的命令行參數,可以用傳統的getopt函數來分析,本文基於面向對象,分析一種管理命令行參數方法 -- 來源於webrtc項目,在閱讀過程中,大家分享一下。
一,傳統命令行分析
包含頭文件:
- #include<unistd.h>
- int getopt(int argc,char * const argv[ ],const char * optstring);
- extern char *optarg;
- extern int optind, opterr, optopt;
二,命令行參數管理
假設命令行的輸入格式的規則如下:
- --flag 布爾類型。
- --noflag 布爾類型。
- --flag=value 等號周邊沒有空格。
2.1 參數的值封裝---FlagValue
這個類對參數的值進行封裝,如--prefix=/usr,作為一個命令行參數時,prefix為鍵,/usr為值。在參數中,在此定義值的類型為布爾、整型、浮點、字符串中的一種。
由於一個值在只能取四種的一種,所以此處用聯合類型表示FlagValue。
- union FlagValue {
- static FlagValue New_BOOL(int b) {
- FlagValue v;
- v.b = (b != 0);
- return v;
- }
-
- static FlagValue New_INT(int i) {
- FlagValue v;
- v.i = i;
- return v;
- }
-
- static FlagValue New_FLOAT(float f) {
- FlagValue v;
- v.f = f;
- return v;
- }
-
- static FlagValue New_STRING(const char* s) {
- FlagValue v;
- v.s = s;
- return v;
- }
-
- bool b;
- int i;
- double f;
- const char* s;
- };
這個聯合類型對命令行中鍵值對中的值進行封裝,可以表示四種類型。
2.2 命令行中鍵值的表示 -- Flag
這個類是表示一對鍵值的抽象,包含下列元素:
- 鍵值對。包括name和variable_表示鍵和值。如--prefix=/usr中,name的值為prefix,variable_為/usr的一個表示。
- 鏈表維護域。Flag *next_用於指向下一個命令行參數。
- comment_表示該參數的解釋。
- file表示和鍵值相關的外部文件。
- default_表示默認情況下,就是用戶沒有輸入該參數的情況下默認的值。
- 定義友元類FlagList,因為FlagList需要訪問Flag的next_域。
- class Flag {
- public:
- enum Type { BOOL, INT, FLOAT, STRING };
-
- // Internal use only.
- Flag(const char* file, const char* name, const char* comment,
- Type type, void* variable, FlagValue default_);
-
- // General flag information
- const char* file() const { return file_; }
- const char* name() const { return name_; }
- const char* comment() const { return comment_; }
-
- // Flag type
- Type type() const { return type_; }
-
- // Flag variables
- bool* bool_variable() const {
- assert(type_ == BOOL);
- return &variable_->b;
- }
-
- int* int_variable() const {
- assert(type_ == INT);
- return &variable_->i;
- }
-
- double* float_variable() const {
- assert(type_ == FLOAT);
- return &variable_->f;
- }
-
- const char** string_variable() const {
- assert(type_ == STRING);
- return &variable_->s;
- }
-
- // Default values
- bool bool_default() const {
- assert(type_ == BOOL);
- return default_.b;
- }
-
- int int_default() const {
- assert(type_ == INT);
- return default_.i;
- }
-
- double float_default() const {
- assert(type_ == FLOAT);
- return default_.f;
- }
-
- const char* string_default() const {
- assert(type_ == STRING);
- return default_.s;
- }
-
- // Resets a flag to its default value
- void SetToDefault();
-
- // Iteration support
- Flag* next() const { return next_; }
-
- // Prints flag information. The current flag value is only printed
- // if print_current_value is set.
- void Print(bool print_current_value);
-
- private:
- const char* file_;
- const char* name_;
- const char* comment_;
-
- Type type_;
- FlagValue* variable_;
- FlagValue default_;
-
- Flag* next_;
-
- friend class FlagList; // accesses next_
- };