最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++命令行解析包gflags的使用教程

 更新時(shí)間:2020年11月24日 10:31:59   作者:悟空小飯  
這篇文章主要給大家介紹了關(guān)于C++命令行解析包gflags的使用教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

gflags 是 Google 提供的一個(gè)命令行參數(shù)處理的開源庫(kù),目前已經(jīng)獨(dú)立開源,比傳統(tǒng)的 getopt() 功能更加強(qiáng)大,可以將不同的參數(shù)定義分布到各個(gè)源碼文件中,不需要集中管理。

提供了 C++ 和 Python 兩個(gè)版本,這里僅詳細(xì)介紹 C++ 版本的使用方式。

簡(jiǎn)介

配置參數(shù)分開還是集中管理沒有嚴(yán)格的約束,關(guān)鍵要看項(xiàng)目里的統(tǒng)一規(guī)范,只是,gflags 可以支持這兩種方式,允許用戶更加靈活的使用。

當(dāng)將參數(shù)分布到各個(gè)源碼文件中時(shí),如果定義了相同的參數(shù),那么在編譯的時(shí)候會(huì)直接報(bào)錯(cuò)。

安裝

很多發(fā)行版本會(huì)有自己相關(guān)的開發(fā)庫(kù),這里簡(jiǎn)單介紹使用 CMake 從源碼進(jìn)行編譯,源碼可以從 GitHub gflags Releases 中選擇相關(guān)的版本。

如下命令以最新的 2.2.2 版本為例。

$ tar xzf gflags-2.2.2.tar.gz
$ cd gflags-2.2.2
$ mkdir build && cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/usr ..
$ make
$ make test # 單元測(cè)試,執(zhí)行cmake時(shí)需要增加-DBUILD_TESTING=true參數(shù)
# make install # 安裝,一般需要root用戶執(zhí)行

默認(rèn)會(huì)安裝到 /usr/local 目錄下,需要配置動(dòng)態(tài)庫(kù)、頭文件路徑等,通過上述的 -DCMAKE_INSTALL_PREFIX=/usr 參數(shù)修改該路徑,使用系統(tǒng)默認(rèn)路徑,此時(shí)會(huì)安裝如下的文件。

/usr/lib/libgflags.a
/usr/lib/libgflags_nothreads.a
/usr/include/gflags/gflags.h
/usr/include/gflags/gflags_declare.h
/usr/include/gflags/gflags_completions.h
/usr/include/gflags/gflags_gflags.h
/usr/lib/cmake/gflags/gflags-config.cmake
/usr/lib/cmake/gflags/gflags-config-version.cmake
/usr/lib/cmake/gflags/gflags-targets.cmake
/usr/lib/cmake/gflags/gflags-targets-release.cmake
/usr/lib/cmake/gflags/gflags-nonamespace-targets.cmake
/usr/lib/cmake/gflags/gflags-nonamespace-targets-release.cmake
/usr/bin/gflags_completions.sh
/usr/lib/pkgconfig/gflags.pc

詳細(xì)的安裝可以參考gflags install.md 中的介紹,可以使用 ccmake 選擇配置項(xiàng),或者使用上述的 cmake + 參數(shù)的方式配置。

示例

假設(shè)有個(gè)網(wǎng)絡(luò)客戶端代碼,需要指定服務(wù)端的地址和端口,希望有默認(rèn)參數(shù),同時(shí)允許用戶通過命令行來指定不同的值。

#include <iostream>
#include <gflags/gflags.h>

DEFINE_string(host, "localhost", "Server host address");
DEFINE_int32(port, 8080, "Server port");

int main(int argc, char **argv)
{
 gflags::ParseCommandLineFlags(&argc, &argv, true);
 std::cout << "Got '" << FLAGS_host << ":" << FLAGS_port << "'." << std::endl;
 return 0;
}

在代碼開頭通過 DEFINE_XXX 定義參數(shù),包括了變量名、默認(rèn)值、參數(shù)介紹等;主程序中使用 gflags::ParseCommandLineFlags() 函數(shù)解析參數(shù);使用時(shí),在變量名稱前添加 FLAGS_ 頭即可。

通過如下命令行進(jìn)行編譯。

g++ main.cc -std=c++11 -o gflags -lgflags -lpthread

默認(rèn)是需要 pthread 線程庫(kù)的,暫時(shí)還不太確定沒有使用多線程時(shí),如何關(guān)閉該參數(shù)。

然后,可以通過如下方式指定參數(shù)。

----- 不指定參數(shù),使用默認(rèn)值
$ ./gflags
Got 'localhost:8080'.

----- 可以選擇指定一個(gè)參數(shù),或者多個(gè)參數(shù)
$ ./gflags -host www.foobar.com
Got 'www.foobar.com:8080'.
$ ./gflags -port 80
Got 'localhost:80'.
$ ./gflags -host www.foobar.com -port 80
Got 'www.foobar.com:80'.

----- 同時(shí)支持不同的參數(shù)指定方式
$ ./gflags --host www.foobar.com --port 80
Got 'www.foobar.com:80'.
$ ./gflags --host=www.foobar.com=--port 80
Got 'www.foobar.com:80'.

同時(shí)也可以使用 --help 參數(shù)查看幫助信息,包含了 gflags 庫(kù)提供的參數(shù),以及用戶提供的參數(shù),如下是輸出的用戶參數(shù)信息。

 Flags from main.cc:
 -host (Server host address) type: string default: "localhost"
 -port (Server port) type: int32 default: 8080

接著看看詳細(xì)使用方式。

使用詳解

包含了如何定義、解析等使用場(chǎng)景。

定義參數(shù)

在如上的示例中定義了兩種類型的參數(shù),分別為字符串 string 和整型 int32 ,包括了變量名、默認(rèn)值、參數(shù)介紹三個(gè)入?yún)?,三個(gè)參數(shù)都是必須的。

gflags 總共提供了六種定義方式 (或者說類型)。

DEFINE_bool boolean
DEFINE_int32 32-bit integer
DEFINE_int64 64-bit integer
DEFINE_uint64 unsigned 64-bit integer
DEFINE_double double
DEFINE_string C++ string

可以定義到某個(gè) NameSpace 下,這樣在使用時(shí)也必須要帶著 NameSpace 前綴。如果在不同的文件中定義,那么可以在某個(gè)集中的頭文件中通過 DECLARE_XXX(VAR) 進(jìn)行聲明。

注意,不要定義相同名稱的參數(shù),即使在不同的 NameSpace 也不可以;還有幾個(gè)保留參數(shù),包括了 flagfile fromenv tryfromenv undefok 等等。

參數(shù)解析

在上述的示例中,通過 ParseCommandLineFlags() 函數(shù)解析參數(shù),另外還有不帶幫助文檔的解析方式,兩個(gè)函數(shù)的聲明如下。

uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags);
uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv, bool remove_flags);

其中 remove_flags 標(biāo)識(shí)指定參數(shù)的處理方式,如果為 true ,那么解析時(shí)會(huì)將 flag 以及 flag 對(duì)應(yīng)的值從 argv 中刪除,并修改 argc ,也就是說,最后存放的是不包含 flag 的參數(shù);如果為 false 則僅對(duì)參數(shù)重排,標(biāo)志位參數(shù)放最前面。

參數(shù)校驗(yàn)

為了檢查參數(shù)的值是否合法,可以針對(duì)某個(gè)參數(shù)注冊(cè)一個(gè)驗(yàn)證函數(shù),當(dāng)參數(shù)解析或者修改 (調(diào)用 SetCommandLineOption() 時(shí)) 該驗(yàn)證函數(shù)都會(huì)被調(diào)用,返回 true 表示校驗(yàn)成功,否則失敗。

如下是對(duì)于 port 參數(shù)的校驗(yàn)。

#include <iostream>
#include <gflags/gflags.h>

DEFINE_string(host, "localhost", "Server host address.");
DEFINE_int32(port, 8080, "Server port.");

static bool ValidatePort(const char *flag, gflags::int32 value)
{
 if (value > 0 && value < 32768)
  return true;
 std::cerr << "Invalid value for --" << flag << ": " << value << std::endl;
 return false;
}
static const bool port_dummy = gflags::RegisterFlagValidator(&FLAGS_port, &ValidatePort);

int main(int argc, char **argv)
{
 gflags::ParseCommandLineFlags(&argc, &argv, true);
 std::cout << "Got '" << FLAGS_host << ":" << FLAGS_port << "'" << std::endl;
 return 0;
}

如果超過了指定的范圍則會(huì)報(bào)錯(cuò)。

使用參數(shù)

提供了默認(rèn)的 --help 查看幫助信息,指定參數(shù)可以使用 - 或者 -- 符號(hào),參數(shù)和值的分割可以使用 ` ` 或者 = ,如上的示例。

對(duì)于布爾類型,還可以使用 --foobar --nofoobar --foobar=true --foobar false 的方式指定。

檢查參數(shù)是否設(shè)置

在通過 ParseCommandLineFlags() 函數(shù)解析完參數(shù)之后,可以通過如下方法檢查對(duì)應(yīng)的變量是否被設(shè)置。

gflags::CommandLineFlagInfo info;
if (gflags::GetCommandLineFlagInfo("port", &info) && info.is_default) {
 std::cout << "port is not set." << std::endl;
} else {
 std::cout << "port is set." << std::endl;
}

這里不是直接比對(duì)的設(shè)置值與默認(rèn)值相同,即使指定了與默認(rèn)值相同的值,也會(huì)被認(rèn)為參數(shù)被修改了。

文件引入

可以通過 --flagfile=FileName 指定參數(shù)文件名,文件名也可以使用通配符 * 以及 ?,在文件中每行標(biāo)識(shí)一個(gè)參數(shù),例如:

$ cat flags.txt
# This is the test server.
--host=www.foobar.com
--port=80
$ ./gflags --flagfile flags.txt
Got 'www.foobar.com:80'.

以 # 開頭的為注釋,也可以再次使用 --flagfile=FileName 包含一個(gè)參數(shù)配置文件。

環(huán)境變量引入

可以使用 --fromenv 或者 --tryfromenv 從環(huán)境變量中引入?yún)?shù),也可通過 --fromenv=foo,bar 指定讀取的參數(shù),當(dāng)然,需要先設(shè)置好環(huán)境變量。

export FLAGS_foo=xxx; export FLAGS_bar=yyy # sh
setenv FLAGS_foo xxx; setenv FLAGS_bar yyy # tcsh

這種方式等價(jià)于在命令行指定 --foo=xxx --bar=yyy 參數(shù)。

其中 --fromenv 時(shí)如果環(huán)境變量不存在則會(huì)報(bào)錯(cuò),而 --tryfromenv 當(dāng)環(huán)境變量中不存在時(shí)會(huì)使用默認(rèn)值。

程序中指定

最常見的是允許用戶動(dòng)態(tài)進(jìn)行配置,也就是說動(dòng)態(tài)加載,可以調(diào)用 SetCommandLineOption() 函數(shù)來實(shí)現(xiàn),函數(shù)的聲明如下。

std::string SetCommandLineOption(const char* name, const char* value);

例如。

gflags::SetCommandLineOption("port", "9999");

成功則會(huì)返回 port set to 9999 字符串,否則會(huì)返回空字符串。

另外也可以通過 bool GetCommandLineOption(const char* name, std::string* OUTPUT) 函數(shù)獲取 flag 的接口,如果沒有指定,則會(huì)通過 OUTPUT 返回默認(rèn)的值,只有當(dāng)指定了一個(gè)未定義的 flag 名稱時(shí),會(huì)返回 false 。

正常讀寫都可以使用 if (FLAGS_foo); FLAGS_Foo = bar 的形式,但是如果需要線程安全的調(diào)用,建議使用這兩個(gè)函數(shù)。

完整示例

如上設(shè)置的完整示例如下。

#include <iostream>
#include <gflags/gflags.h>

DEFINE_string(host, "localhost", "Server host address.");
DEFINE_int32(port, 8080, "Server port.");

static bool ValidatePort(const char *flag, gflags::int32 value)
{
 if (value > 0 && value < 32768)
  return true;
 std::cerr << "Invalid value for --" << flag << ": " << value << std::endl;
 return false;
}
static const bool port_dummy = gflags::RegisterFlagValidator(&FLAGS_port, &ValidatePort);

int main(int argc, char **argv)
{
 gflags::SetVersionString("1.1.0");
 gflags::SetUsageMessage("./gflags");
 gflags::ParseCommandLineFlags(&argc, &argv, true);

 std::cout << gflags::SetCommandLineOption("port", "999") << std::endl;

 std::cout << "Got '" << FLAGS_host << ":" << FLAGS_port << "'" << std::endl;
 return 0;
}

可以通過 g++ main.cc -std=c++11 -o gflags -lgflags -lpthread 命令編譯。

其它

常用參數(shù)

gflags 中包含了幾類默認(rèn)的參數(shù)。

--help        顯示所有文件的所有flag,按文件、名稱排序,顯示flag名、默認(rèn)值和幫助
--helpfull    和 --help 相同,顯示全部flag
--helpshort    只顯示執(zhí)行文件中包含的flag,通常是 main() 所在文件
--helpxml    類似 --help,但輸出為xml
--helpon=FILE  只顯示定義在 FILE.* 中得flag
--helpmatch=S  只顯示定義在 *S*.* 中的flag
--helppackage  顯示和 main() 在相同目錄的文件中的flag
--version    打印執(zhí)行文件的版本信息

--undefok=flagname,flagname,...  后面列出的flag名,可以在無定義的情況下忽略而不報(bào)錯(cuò)

--fromenv --tryfromenv   從環(huán)境變量中引入
--flagfile               從文件中引入

定制版本和幫助信息

通過 --version 和 --help 默認(rèn)會(huì)輸出其對(duì)應(yīng)的版本和幫助信息,也可以通過 SetVersionString() 設(shè)置版本信息,通過 SetUsageMessage() 設(shè)置幫助的開始軟件信息 (幫助信息無法覆蓋)。

gflags::SetVersionString("1.1.0");
gflags::SetUsageMessage("./gflags");

注意,參數(shù)的設(shè)置需要在調(diào)用 ParseCommandLineFlags() 之前。

CMake 使用

最新版本的 gflags 已經(jīng)可以支持 CMake 了,如上安裝時(shí)所示,在安裝時(shí)會(huì)在 /usr/lib/cmake/gflags/ 目錄下安裝相關(guān)的文件,那么在項(xiàng)目中可以通過如下方式使用。

FIND_PACKAGE(gflags REQUIRED)
INCLUDE_DIRECTORIES(${gflags_INCLUDE_DIR})

ADD_EXECUTABLE(foo main.cc)
TARGET_LINK_LIBRARIES(foo gflags)

如果是將 CMake 安裝到了其它路徑下,那么可以將上述的文件復(fù)制到 CMake 的模塊路徑下再使用。

整型選擇

在 gflags/gflags_declare.h 中定義了 int32 int64 等類型,可以直接使用,不過編譯時(shí)需要添加 -std=c++11 參數(shù),否則在使用 cstdint 頭文件時(shí)會(huì)報(bào)錯(cuò)。

其它

可以通過 void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT) 接口遍歷所有的參數(shù),更多接口可以查看 gflags/gflags.h 頭文件。

參考

詳細(xì)可以查看官方文檔 How To Use gflags 中的介紹。

到此這篇關(guān)于C++命令行解析包gflags使用教程的文章就介紹到這了,更多相關(guān)C++命令行解析包gflags使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C 語言基礎(chǔ)教程(我的C之旅開始了)[二]

    C 語言基礎(chǔ)教程(我的C之旅開始了)[二]

    C 語言基礎(chǔ)教程(我的C之旅開始了)[二]...
    2007-02-02
  • iOS鎖屏音頻播放控制及音頻信息設(shè)置

    iOS鎖屏音頻播放控制及音頻信息設(shè)置

    這篇文章主要為大家詳細(xì)介紹了iOS鎖屏音頻播放控制及音頻信息設(shè)置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • QT編寫簡(jiǎn)單登錄界面的實(shí)現(xiàn)示例

    QT編寫簡(jiǎn)單登錄界面的實(shí)現(xiàn)示例

    登陸界面是網(wǎng)頁中常見的界面,本文主要介紹了QT編寫簡(jiǎn)單登錄界面的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • C語言中sizeof函數(shù)的基本使用總結(jié)

    C語言中sizeof函數(shù)的基本使用總結(jié)

    這篇文章主要給大家介紹了關(guān)于C語言中sizeof函數(shù)的基本使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • C++實(shí)現(xiàn)查找中位數(shù)的O(N)算法和Kmin算法

    C++實(shí)現(xiàn)查找中位數(shù)的O(N)算法和Kmin算法

    這篇文章主要介紹了C++實(shí)現(xiàn)查找中位數(shù)的O(N)算法和Kmin算法,對(duì)于C++程序算法設(shè)計(jì)有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-09-09
  • 最新評(píng)論

    府谷县| 钟祥市| 扶绥县| 桐乡市| 微山县| 资兴市| 江口县| 江孜县| 青龙| 贵溪市| 普陀区| 榆树市| 宜兰市| 吐鲁番市| 米泉市| 新民市| 尼玛县| 绵竹市| 忻城县| 容城县| 叙永县| 垣曲县| 永兴县| 额尔古纳市| 石门县| 吉安县| 凤庆县| 隆安县| 漳平市| 白银市| 中江县| 乐都县| 新化县| 清河县| 平邑县| 历史| 崇义县| 田林县| 玛沁县| 翁牛特旗| 云南省|