Google開源命令列引數解析庫gflags
今天寫程式時需要寫一個命令列解析程式,於是網上搜索getopt()的實現程式碼,但搜到的資訊基本上是如何使用getopt(),而系統又是Windows的;於是想到了以前專案中使用到的Google開源命令列解析庫gflags。
google開源的gflags是一套命令列引數解析工具,他可以替代getopt(),使用起來更加方便靈活,包括支援C++內建的型別如string,gflags還支援從環境變數、配置檔案讀取引數(可用gflags代替配置檔案)。本文簡單介紹gflags的安裝與使用。
gflags的安裝
gflags原始碼可以按照https://code.google.com/p/gflags/
gflags-2.1.1.zip,當然tar.gz也可以的。下載完後解壓,這時候原始碼並不能直接放在應用程式中引用,因為看網上好多例子都include <gflags/gflags.h>,而壓縮完的原始碼中並沒有gflags.h,但是注意到src目錄中有個gflags.h.in檔案,想必是需要做什麼操作將gflags.h.in檔案轉換為gflags.h;繼續瀏覽根目錄gflags-2.1.1,可以看到有個INSTALL.txt檔案,可惜裡面都是一些Linux安裝操作,再看有個CMakeLists.txt檔案,這個檔案是CMake工具生成工程必備的檔案,於是用CMake生成VS工程配置:
點選Configure,出現報錯資訊:
[plain] view plaincopyprint?- The CXX compiler identification is MSVC 16.0.30319.1
- Check for working CXX compiler using: Visual Studio 10
- Check for working CXX compiler using: Visual Studio 10 -- broken
-
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake:54 (message):
- The C++ compiler "C:/Program Files (x86)/Microsoft Visual Studio
- 10.0/VC/bin/cl.exe" is not able to compile a simple test program.
- It fails with the following output:
- Change Dir: D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeTmp
- Run Build Command:C:\PROGRA~2\MICROS~2.0\Common7\IDE\devenv.com
- CMAKE_TRY_COMPILE.sln /build Debug /project cmTryCompileExec1038135002
- Microsoft(R) Visual Studio 10.0.30319.1 版。
- 版權所有(C) Microsoft Corp。保留所有權利。
- 1>------ 已啟動生成: 專案: cmTryCompileExec1038135002, 配置: Debug Win32
- ------
- 1>生成啟動時間為 2014/5/5 19:27:03。
- 1>PrepareForBuild:
- 1>
- 正在建立目錄“D:\software\gflags-2.1.1\cmake-bin\CMakeFiles\CMakeTmp\Debug\”。
- 1>InitializeBuildStatus:
- 1>
- 正在建立“cmTryCompileExec1038135002.dir\Debug\cmTryCompileExec1038135002.unsuccessfulbuild”,因為已指定“AlwaysCreate”。
- 1>ClCompile:
- 1> 用於 80x86 的 Microsoft (R) 32 位 C/C++ 優化編譯器 16.00.30319.01 版
- 1> 版權所有(C) Microsoft Corporation。保留所有權利。
- 1>
- 1> cl /c /Zi /W3 /WX- /Od /Ob0 /Oy- /D WIN32 /D _WINDOWS /D _DEBUG /D
- "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise
- /Zc:wchar_t /Zc:forScope /GR /Fo"cmTryCompileExec1038135002.dir\Debug\\"
- /Fd"cmTryCompileExec1038135002.dir\Debug\vc100.pdb" /Gd /TP /analyze-
- /errorReport:prompt testCXXCompiler.cxx
- 1>
- 1> testCXXCompiler.cxx
- 1>LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞
- 1>
- 1>生成失敗。
- 1>
- 1>已用時間 00:00:00.98
- ========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========
- CMake will not be able to correctly generate this project.
- Call Stack (most recent call first):
- CMakeLists.txt:16 (project)
- Configuring incomplete, errors occurred!
- See also "D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeOutput.log".
- See also "D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeError.log".
LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞
生成ALL_BUILD專案,然後生成INSTALL專案,這裡安裝時可能會出以下錯誤:
[plain] view plaincopyprint?- C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: 命令“setlocal
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -DBUILD_TYPE=Debug -P cmake_install.cmake
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmEnd
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmErrorLevel
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: exit /b %1
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmDone
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
- 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :VCEnd”已退出,程式碼為 1。
這個一般是許可權問題,退出VS,重新以管理員省份開啟該工程,再次生成INSTALL專案就沒有問題了;在C:\Program Files (x86)目錄中可以看到已經有gflags目錄,之後就可以引用該目錄下的庫進行程式設計了。在這裡為方便大家不用做以上操作,直接獲得gflags庫的使用,這裡提供我已經編譯好的庫和標頭檔案,地址為:http://download.csdn.net/detail/lming_08/7352863
gflags的使用
使用flags需要包含標頭檔案 #include <gflags/gflags.h>gflags主要支援的引數型別包括bool,int32, int64, uint64, double, string等,定義引數通過DEFINE_type巨集實現,如下所示,分別定義了一個bool和一個string型別的引數,該巨集的三個引數含義分別為命令列引數名,引數預設值,以及引數的幫助資訊。
[cpp] view plaincopyprint?
- 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");
定義以上引數後,就需要在main()函式中執行gflags::ParseCommandLineFlags(&argc, &argv, true);
然後就可以在應用程式中使用FLAGS_big_menu、FLAGS_languages表示獲取到的命令列引數值。
注意:直接#include <gflags/gflags.h>並連結上gflags.lib或gflags_nothreads.lib,應用程式可能並不能連結成功,可能會生成如下報錯資訊:
[plain] view plaincopyprint?- gflags.lib(gflags.obj) : error LNK2019: 無法解析的外部符號 [email protected],該符號在函式 "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall gflags::`anonymous namespace'::CommandLineFlagParser::ProcessOptionsFromStringLocked(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,enum gflags::FlagSettingMode)" ([email protected]@[email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z) 中被引用
查閱資料發現是沒有連結上shlwapi.lib,而shlwapi.lib是已經被廢棄的庫;連結上shlwapi.lib庫後再次編譯連結就OK了。
考慮到shlwapi.lib和gflags庫都是靜態庫,因此可以在生成gflags庫時連結上shlwapi.lib,這樣在應用程式中就不用額外地再連結上shlwapi.lib了。
另外需要注意的是,在VS【屬性】-【除錯】中設定的原始命令列引數argv[]中表示字串內容不僅僅是設定的相應字串,他會在字串前加上工程路徑名,而gflags中就沒有了工程路徑名,設定的多少就是多少。
參考資料:
相關推薦
Google開源命令列引數解析庫gflags
今天寫程式時需要寫一個命令列解析程式,於是網上搜索getopt()的實現程式碼,但搜到的資訊基本上是如何使用getopt(),而系統又是Windows的;於是想到了以前專案中使用到的Google開源命令列解析庫gflags。 google開源的gflags是一套命令列引數解析工具,他可以替代getopt
gflags(google開源的一套命令列引數解析工具)
gflags是google開源的一套命令列引數解析工具,比getopt()函式功能要強大,使用起來更加方便,gflags還支援從環境變數和配置檔案中讀取引數。目前有C++和Python版本。本文就來詳細介紹C++版本gflags的使用,主要分如下兩個部分 Cont
C++ 命令列引數解析
文章目錄 說明 短引數之 getopt() 長引數之 getopt_long() 長引數之 getopt_long_only() 說明 主要參考以下部落格: 部落格一:getopt和g
【tensorflow】命令列引數解析
1. tf.app.flags,用於支援接受命令列傳遞引數 import tensorflow as tf #第一個是引數名稱,第二個引數是預設值,第三個是引數描述 tf.app.flags.DEFINE_string('str_name', 'def_v_1',"descrip1")
golang命令列引數解析
package main import ( "fmt" "os" ) func main(){ s:= os.Args fmt.Println(s) } 直接執行 輸出結果:[C:\Users\Administrator\AppData\Local\Temp\___go_bui
python命令列引數解析
一、getopt模組 getopt.getopt(args, options[, long_options]) args為需要解析的命令列引數列表,一般為sys.argv[1:],這是因為argv[0]為指令碼的路徑。 options為希望識別的引數,如果該命令列引數
python 命令列引數解析 argparse簡單分析
在python 2.7 後,不推薦使用 optparse, 而推薦使用 argparse. 其它的不多說,簡單的分析下我遇到的問題:我是想用 argparse 來解析不定長的命令列引數 例如: import argparse import sys parser = ar
命令列引數解析
對這種主函式形式一直不是很瞭解,今天研究了一下,所得如下: 當我們成功執行一個程式時,在Windows環境下會生成一個exe檔案,我們可以再命令列中開啟並執行這個程式。 比如說如下程式碼。 #
Golang: 使用flag包進行命令列引數解析
最近在使用go開發cli(command-line-interface)時,通過對於官方文件以及他人部落格的學習,在此寫下個人認為更適合自己往後回顧的關於flag的使用說明。 工欲善其事必先利其器,先奉上flag官方文件解析 Demo0: pack
ffmpeg 原始碼學習 -- 之命令列引數解析
ffmpeg 原始碼學習 -- 之ffmpeg命令列引數解析 大家通過git在安裝好cygwin之後,下載原始碼到(cygwin)home目錄,通過./configure ...... ,可以新增一堆引數選項,執行可以生成config.mk等編譯使用的檔案,通過命令對工
Tensorflow:tf.app.run()與命令列引數解析
首先給出一段常見的程式碼: if __name__ == '__main__': tf.app.run()12 它是函式入口,通過處理flag解析,然後執行main函式(或者接下來提到的xxx())(最後含有tf.app.run()的檔案,在此行之前肯定能找到def main
Python命令列引數解析模組argparse
當寫一個Python指令碼時經常會遇到不同引數不同功能的情況,如何做一個更好看的命令幫助資訊以及對命令引數解析呢? 這就需要使用argparse模組 #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import os impor
命令列引數解析函式getopt_long() 使用詳解
當一個用C語言編寫的Linux或UNIX程式執行時,它是從main函式開始的。對這些程式而言,main函式的宣告如下所示: int main(int argc, char *argv[]) 其中argc是程式引數的個數(int),argv是一個代表引數自身的
getopt(win32) -- 命令列引數解析函式
GNU libc提供了getopt和getopt_long用於解析命令列引數,很好用,想在windows下使用,就google了幾個win32下的C/C++寫得getopt,並作了一些比較。 程式裡往往會有許多開關的,執行時就要傳入許多引數值來開啟或關閉這些開關。以前
命令列引數解析函式--getopt
原型: #include <unistd.h> int getopt(int argc, char * const argv[], const char *optstring); 該函式的argc和argv引數通常直接從main()的引數直接傳遞而來。opt
C 語言命令列引數解析
C語言原始碼必須有且只有一個的函式是main函式,我們知道函式可以有引數,那麼main函式有沒有引數呢? 顯然是有的,而且它是固定的,只有兩個,第一個是整型變數(argc),第二個是字元型指標陣列(a
一個命令列引數解析器
因工作需要寫一個console工具程式,執行引數很多,記得linux下有一個系統函式getopt可以很好得幫助程式設計師解析命令列引數,但是在VC中沒有這個函式,研究了下linux中對該函式的幫助資訊和標頭檔案g
使用Apache commons-cli包進行命令列引數解析
Apache的commons-cli包是專門用於解析命令列引數格式的包。 依賴: <dependency> <groupId>commons-cli</groupId> <artifactId&g
linux命令列引數解析學習心得
轉載出處:blog.csdn.net/bailyzheng/article/details/8048733 最近用到一個命令列工具,之前也一直說想把命令列引數解析看一下,今天算是做一個小的總結。 命令列引數解析分類:單個字元的引數(-a -b),還有字串引數(--vide
linux命令列引數解析函式 getopt
在學習開原始碼過程中,經常遇到命令列解析函式 getopt,網上查閱了一些資料,總結一下。 說到命令列解析,最簡單的方式就是利用c語言main函式的兩個引數argc和argv來實現,當 C 執行時庫程式啟動程式碼呼叫 main() 時,會將命令列的引數傳過來,引數個數放在a