Google gflags庫(解析命令列引數)
google gflags是google使用的一個開源庫,用於解析命令列標記。目前的gflags有C++和Python兩個版本。本文主要介紹gflags的C++版本使用方法。
命令列標記是指使用者在執行可執行程式時,在命令列中指定的引數。例如,對於命令:
- fgrep -l -f /var/tmp/foo johannes brahms
則-l及-f /var/tmp/foo是兩個命令列標記,而johnnes和brahms則是命令列引數。一個應用往往具有許多個命令列標記,對應這些標記,可以傳入一些由使用者指定的引數。例如,在上面的例子中,-l標記沒有任何引數,而-f標記的引數則是/var/tmp/foo
這些標記和引數儲存在main函式的argc和argv引數中。一般而言,main函式總有如下的形式:
- int main(int argc, char ** argv) {…}
其中argc指明瞭argv陣列的長度,而argv陣列則空格為分割,儲存命令列後用戶輸入的引數。在GNU C Library中,這個工作主要是由getopt函式來完成的。以下是getopt函式的一個例子:
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
-
#include <unistd.h>
- int
- main (int argc, char **argv)
- {
- int aflag = 0;
- int bflag = 0;
- char *cvalue = NULL;
- int index;
- int c;
- opterr = 0;
- while ((c = getopt (argc, argv, "abc:")) != -1)
- switch (c)
- {
- case'a':
- aflag = 1;
- break;
-
case
- bflag = 1;
- break;
- case'c':
- cvalue = optarg;
- break;
- case'?':
- if (optopt == 'c')
- fprintf (stderr, "Option -%c requires an argument.\n", optopt);
- elseif (isprint (optopt))
- fprintf (stderr, "Unknown option `-%c'.\n", optopt);
- else
- fprintf (stderr,
- "Unknown option character `\\x%x'.\n",
- optopt);
- return 1;
- default:
- abort ();
- }
- printf ("aflag = %d, bflag = %d, cvalue = %s\n",
- aflag, bflag, cvalue);
- for (index = optind; index < argc; index++)
- printf ("Non-option argument %s\n", argv[index]);
- return 0;
- }
在這個例子中可以看出,所有的標記的定義都必須要集中在一個地方處理(也就是switch程式碼段中)。而gflags則與getopt函式不同,在gflags中,標記的定義分散在原始碼中,不需要列舉在一個地方。這意味著單個的原始碼檔案可以定義他們自己所使用的標記,一切連線到這個檔案的應用將獲取這個標記,並且gflags將自動對這個標記進行適當的處理。這對於軟體的靈活性及程式碼的重用是很有好處的。當然,這也產生了一定的風險,特別是,兩個不同的檔案可能會定義擁有同一個名字的命令列標記,在平常的情況下沒有問題,但當這兩個檔案被同一個二進位制程式連線的時候,就會出現錯誤。
gflags使用C++語言實現,其風格也是C++風格的。本文的其餘部分介紹瞭如何使用gflags。
一、如何定義一個命令列標記
使用gflags需要引用gflags標頭檔案:
#include <gflags/gflags.h>
在gflags.h檔案的結尾,定義了一些標記定義巨集,因此在引用了gflags.h後,定義一個命令列標記就變得十分簡單了。如,在foo.cc檔案的開頭,我們引入如下的命令列標記的定義:
- #include <gflags/gflags.h>
- DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
- DEFINE_string(languages, "english,french,german”,"comma-separated list of languages to offer in the 'lang' menu");
在這段程式碼中,我們定義了兩個命令列標記:bool型的big_menu,以及string型的language。所有的DEFINE巨集都有三個引數:標記的名字,預設值,以及針對這個標記的說明。第三個引數是非常有用的,尤其是在構建大型程式的時候,在命令列中使用—help標記可以列出被gflags所定義的所有標記的型別、預設值及對其的說明(也就是巨集第三個引數)。
DEFINE巨集支援的型別包括:
o DEFINE_bool: boolean
o DEFINE_int32: 32-bit integer
o DEFINE_int64: 64-bit integer
o DEFINE_uint64: unsigned 64-bit integer
o DEFINE_double: double
o DEFINE_string: C++ string
可以在可執行程式的任何一個原始檔中定義一個標記,而針對每個標記,只需要定義一次。如果想要在不同的原始檔中訪問該標記,可以使用DECLARE巨集來宣告這個標記(其實就是聲明瞭一個extern變數的引用)。一個更好的方法是,對於一個標記,可以在foo.cc中定義它,並且在foo.h中宣告它。這樣,包含了foo.h的所有原始檔都可以引用這個標記。
二、如何訪問一個標記
訪問標記較為簡單。只要對標記進行了定義或者宣告,那麼只需要在使用它的地方加上字首“FLAGS_”就可以引用這個標記了。如,
- if (FLAGS_consider_made_up_languages)
- FLAGS_languages += ",klingon"; // implied by --consider_made_up_language
- if (FLAGS_languages.find("finnish") != string::npos)
- HandleFinnish();
三、在命令列中使用標記
對於上面的foo.cc和foo.h,如果其編譯後產生的二進位制檔案為app_containing_foo,則在命令列中設定這些標記的方法為:
app_containing_foo --nobig_menu -languages="chinese,japanese,korean" …
這個命令會把big_menu設定為false,並且將language設定為“chinese,japanese,Korean”。對於string、int、double等型別的標記,設定標記時使用如下形式:
o app_containing_foo --languages="chinese,japanese,korean"
o app_containing_foo -languages="chinese,japanese,korean"
o app_containing_foo --languages "chinese,japanese,korean"
o app_containing_foo -languages "chinese,japanese,korean"
這些方式是等價的。但注意gflags不支援短標記與合併標記。如ls –la這種型別,是不能夠被gflags處理的。這和getopt函式有所不同。
需要注意的還有以下幾點:
1,--連用會終止標記。如命令:foo -f1 1 -- -f2 2,則f2標記將不被處理;
2,bool型的標記,如big_menu,既可以使用—big_menu=true/false,也可以使用—big_menu/--nobig_menu這種方式。gflags都可以解析。
3,使用未被定義的標記將引發嚴重錯誤。
四、在程式中解析標記
在程式中解析標記可以使用如下函式:
- google::ParseCommandLineFlags(&argc, &argv, true);
注意argc和argv均以地址方式傳遞,也就是該函式可以改變argc和argv的內容。通常這段程式碼會出現在main函式的開始。最後一個引數是移除標記,它指明瞭是否將被gflags成功解析的標記從引數列表中移除。例如,對於命令列:
foo –options=start file1 file2
在這個命令列中,options是一個命令列標記,將被gflags解析(如果它已經被定義了);而file1和file2則是命令列引數。如果設定remove標記位ture,則—options=start會在呼叫ParseCommandLineFlags後被移除,此時argc=2,而argv中則儲存了file1和file2兩個引數。如果remove標記位設為false,則—options=start將不會被移除,則argc不會改變,但argv會重新排列,將所有的標記排列在前面。
學習資料參考於:
<<用Google的gflags優雅的解析命令列引數>>
http://www.leoox.com/?p=270
<<google gflag使用指南>>
http://blog.csdn.net/starays/article/details/7990984
相關推薦
Google gflags庫(解析命令列引數)
google gflags是google使用的一個開源庫,用於解析命令列標記。目前的gflags有C++和Python兩個版本。本文主要介紹gflags的C++版本使用方法。 命令列標記是指使用者在執行可執行程式時,在命令列中指定的引數。例如,對於命令: fgre
用Google的gflags優雅的解析命令列引數(一)
寫了這麼多年的Linux下C/C++程式碼,一直使用getopt_long來解析命令列引數,同時定義一個全域性的struct來儲存各個命令列引數的值。雖然用得比較“繁瑣”,但也安於現狀。最近突然發現了Google早在多年前就開源了一個解析命令列引數的“神器”gflags。趕
get_optlong用法(linux解析命令列引數)
const char * const shor_options = “ho:v” ;struct option 型別陣列該資料結構中的每個元素對應了一個長選項,並且每個元素是由四個域組成。通常情況下,可以按以下規則使用。第一個元素,描述長選項的名稱;第二個選項,代表該選項是否需要跟著引數,需要引數則為1,反
gflags(google開源的一套命令列引數解析工具)
gflags是google開源的一套命令列引數解析工具,比getopt()函式功能要強大,使用起來更加方便,gflags還支援從環境變數和配置檔案中讀取引數。目前有C++和Python版本。本文就來詳細介紹C++版本gflags的使用,主要分如下兩個部分 Cont
FFmpeg 解析命令列引數
FFmpeg 命令列基礎語法: ffmpeg [global_options] {[input_file_options] -i input_file}...{[output_file_options] output_file}... global_options:全域性引
go語言解析命令列引數的實現
一、實現程式碼如下 // fffggg project main.go package main import ( "flag" "fmt" ) func main() { var num int var mode string
Python解析命令列引數
使用Python編寫應用程式或是指令碼的時候,經常會用到命令列引數。C語言中有庫函式getopt解析短命令列引數,使用getopt_long解析短命令和長命令的組合。 Python使用getopt模組,同時解析短命令和長命令。看具體使用例子 #!/usr/bin/python import sys
linux中getopt_long解析命令列引數(附上windows上的getopt_long原始碼)
getopt_long支援長選項的命令列解析,使用man getopt_long,得到其宣告如下: #include <getopt.h> int getopt_long(int argc, char * const argv[
C語言-解析命令列引數
#include <stdio.h> #include<unistd.h> /* 函式說明 : int getopt(int argc,char * const argv[ ],const char * optstring);) 用來分析命令
使用 Qt 解析命令列引數
Qt解析命令列 我們使用 Python 寫個簡單的指令碼很方便,直接 import argparse 就能很容易的實現命令列引數解析的功能,還可以通過 --help 來輸出幫助功能,而 Qt5 頁提供了這方面的支援。 Qt 從 Qt5.2之後提供了 QCom
getopt、getopt_long和getopt_long_only解析命令列引數
一:posix約定: 下面是POSIX標準中關於程式名、引數的約定: 程式名不宜少於2個字元且不多於9個字元; 程式名應只包含小寫字母和阿拉伯數字; 選項名應該是單字元或單數字,且以短橫 ‘-’ 為
3.QT中QCommandLineParser和QCommandLineOption解析命令列引數
1新建專案 main.cpp #include<QCoreApplication> #include<QCommandLineParser>
linux 中解析命令列引數(getopt_long用法)
getopt_long支援長選項的命令列解析,使用man getopt_long,得到其宣告如下: #include <getopt.h> int getopt_long(int argc, char * const argv[], const cha
Google開源命令列引數解析庫gflags
今天寫程式時需要寫一個命令列解析程式,於是網上搜索getopt()的實現程式碼,但搜到的資訊基本上是如何使用getopt(),而系統又是Windows的;於是想到了以前專案中使用到的Google開源命令列解析庫gflags。 google開源的gflags是一套命令列引數解析工具,他可以替代getopt
Apollo程式碼解析:3. 命令列引數傳遞google gflags
簡介 在百度Apollo中gflag被廣泛的應用在各種全域性變數中,例如節點名,變數名,各種狀態標誌中。 gflags 是google開源的一套命令列引數解析工具,比 getopt 功能更加強大,使用起來更加方便。 什麼是 命令列引數解析工具 呢? 這裡拿p
google gflags 處理命令列引數
#include <string> #include <iostream> #include <gflags/gflags.h> using namespace std; DEFINE_string(input_path, "empty" , "input f
glib命令列解析庫簡單使用--GOptionEntry 命令列引數
轉自:http://blog.csdn.net/ciahi/archive/2010/12/15/6076786.aspx 官網文件為: http://library.gnome.org/devel/glib/stable/glib-Commandline-option-p
linux shell中的命令自動補全(compgen complete)與 命令列引數解析
很多時候,當我們寫一個指令碼時,我們總會提供一些可選的命令選項。當可選項比較多的時候,比如git, 如果能夠提供命令自動補全,無疑是錦上添花的事。而且個人認為,這種方式,比採用將命令做成選擇選單要更好一些。 假設我們現在這樣一個指令碼,指令碼執行命令時bsu, 類似gi
Sqlmap命令列引數解析(一)
前言本文轉載自werner-wiki的部落格,便於參考學習(侵權刪)原文地址:https://blog.csdn.net/wn314/article/details/78872828。一、Sqlmap是什麼Sqlmap是開源的自動化SQL注入工具,由Python寫成,具有如下
MFC解析啟動命令列引數——CCommandLineInfo類
MFC中CCommandLineInfo類被用於分析啟動應用時的命令列引數。 MFC應用一般都會在它的應用物件中使用函式InitInstance()建立這個類的一個本地例項。然後把該物件傳給CWinApp::ParseCommandLine(),ParseCommandLine()又重複呼叫