欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?Boost?ProgramOptions超詳細(xì)講解

 更新時間:2022年11月30日 09:16:28   作者:無水先生  
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱

一、說明

Boost.ProgramOptions

Boost.ProgramOptions 是一個可以輕松解析命令行選項的庫,例如,控制臺應(yīng)用程序。如果您使用圖形用戶界面開發(fā)應(yīng)用程序,命令行選項通常并不重要。

要使用 Boost.ProgramOptions 解析命令行選項,需要以下三個步驟:

  • 定義命令行選項。您給它們命名并指定哪些可以設(shè)置為一個值。如果命令行選項被解析為鍵/值對,您還可以設(shè)置值的類型——例如,它是字符串還是數(shù)字。
  • 使用解析器評估命令行。您可以從 main() 的兩個參數(shù)獲取命令行,這兩個參數(shù)通常稱為 argc 和 argv。
  • 存儲解析器評估的命令行選項。 Boost.ProgramOptions 提供了一個派生自 std::map 的類,它將命令行選項保存為名稱/值對。之后,您可以檢查存儲了哪些選項以及它們的值是什么。

二、示例Boost.ProgramOptions

Example 63.1

示例 63.1。展示了使用 Boost.ProgramOptions 解析命令行選項的基本方法。

示例 63.1。 Boost.ProgramOptions 的基本方法

#include <boost/program_options.hpp>
#include <iostream>
using namespace boost::program_options;
void on_age(int age)
{
  std::cout << "On age: " << age << '\n';
}
int main(int argc, const char *argv[])
{
  try
  {
    options_description desc{"Options"};
    desc.add_options()
      ("help,h", "Help screen")
      ("pi", value<float>()->default_value(3.14f), "Pi")
      ("age", value<int>()->notifier(on_age), "Age");
    variables_map vm;
    store(parse_command_line(argc, argv, desc), vm);
    notify(vm);
    if (vm.count("help"))
      std::cout << desc << '\n';
    else if (vm.count("age"))
      std::cout << "Age: " << vm["age"].as<int>() << '\n';
    else if (vm.count("pi"))
      std::cout << "Pi: " << vm["pi"].as<float>() << '\n';
  }
  catch (const error &ex)
  {
    std::cerr << ex.what() << '\n';
  }
}

要使用 Boost.ProgramOptions,請包含頭文件 boost/program_options.hpp。您可以在命名空間 boost::program_options 中訪問此庫中的所有類和函數(shù)。

使用類 boost::program_options::options_description 來描述命令行選項。這種類型的對象可以寫入諸如 std::cout 之類的流,以顯示可用命令行選項的概覽。傳遞給構(gòu)造函數(shù)的字符串為概覽提供了一個名稱,作為命令行選項的標(biāo)題。

boost::program_options::options_description 定義了一個成員函數(shù) add() ,它需要一個 boost::program_options::option_description 類型的參數(shù)。您調(diào)用此函數(shù)來描述每個命令行選項。示例 63.1 不是為每個命令行選項調(diào)用此函數(shù),而是調(diào)用成員函數(shù) add_options(),這使得該任務(wù)更容易。

add_options() 返回一個代表 boost::program_options::options_description 類型對象的代理對象。代理對象的類型無關(guān)緊要。更有趣的是代理對象簡化了許多命令行選項的定義。它使用重載運算符 operator(),您可以調(diào)用它來傳遞所需的數(shù)據(jù)以定義命令行選項。此運算符返回對同一代理對象的引用,這允許您多次調(diào)用 operator()。

Example 63.1

示例 63.1 在代理對象的幫助下定義了三個命令行選項。第一個命令行選項是 --help。此選項的說明設(shè)置為“幫助屏幕”。該選項是一個開關(guān),而不是名稱/值對。您可以在命令行上設(shè)置 --help 或忽略它。無法將 --help 設(shè)置為一個值。

請注意,傳遞給 operator() 的第一個字符串是“help,h”。您可以為命令行選項指定簡稱。短名稱必須僅由一個字母組成,并設(shè)置在逗號之后?,F(xiàn)在可以使用 --help 或 -h 顯示幫助。

除了 --help 之外,還定義了另外兩個命令行選項:--pi 和 --age。這些選項不是開關(guān),它們是名稱/值對。 --pi 和 --age 都應(yīng)設(shè)置為一個值。

您將指向類型為 boost::program_options::value_semantic 的對象的指針作為第二個參數(shù)傳遞給 operator() 以將選項定義為名稱/值對。您不需要直接訪問 boost::program_options::value_semantic。您可以使用輔助函數(shù) boost::program_options::value(),它創(chuàng)建一個類型為 boost::program_options::value_semantic 的對象。 boost::program_options::value() 返回對象的地址,然后您可以使用 operator() 將其傳遞給代理對象。

boost::program_options::value() 是一個函數(shù)模板,它將命令行選項值的類型作為模板參數(shù)。因此,命令行選項 --age 需要一個整數(shù),而 --pi 需要一個浮點數(shù)。

從 boost::program_options::value() 返回的對象提供了一些有用的成員函數(shù)。例如,您可以調(diào)用 default_value() 來提供默認(rèn)值。如果未在命令行中使用該選項,則示例 63.1 將 --pi 設(shè)置為 3.14。
notifier() 將函數(shù)鏈接到命令行選項的值。然后使用命令行選項的值調(diào)用該函數(shù)。在示例 63.1 中,函數(shù) on_age() 鏈接到 --age。如果命令行選項 --age 用于設(shè)置年齡,則年齡將傳遞給 on_age() 并將其寫入標(biāo)準(zhǔn)輸出。

使用 on_age() 等函數(shù)處理值是可選的。您不必使用 notifier(),因為可以通過其他方式訪問值。

定義所有命令行選項后,您可以使用解析器。在示例 63.1 中,輔助函數(shù) boost::program_options::parse_command_line() 被調(diào)用來解析命令行。此函數(shù)采用定義命令行的 argc 和 argv,以及包含選項說明的 desc。 boost::program_options::parse_command_line() 在 boost::program_options::parsed_options 類型的對象中返回解析后的選項。你通常不直接訪問這個對象。相反,您將它傳遞給 boost::program_options::store(),它將解析的選項存儲在容器中。

示例 63.1 將 vm 作為第二個參數(shù)傳遞給 boost::program_options::store()。 vm 是 boost::program_options::variables_map 類型的對象。此類派生自類 std::map<std::string, boost::program_options::variable_value>,因此提供與 std::map 相同的成員函數(shù)。例如,您可以調(diào)用 count() 來檢查某個命令行選項是否已被使用并存儲在容器中。

在示例 63.1 中,在訪問 vm 和調(diào)用 count() 之前,調(diào)用了 boost::program_options::notify()。此函數(shù)觸發(fā)諸如 on_age() 之類的函數(shù),這些函數(shù)使用 notifier() 鏈接到一個值。如果沒有 boost::program_options::notify(),將不會調(diào)用 on_age()。

vm 可以讓您檢查某個命令行選項是否存在,還可以讓您訪問命令行選項設(shè)置的值。該值的類型是 boost::program_options::variable_value,一個在內(nèi)部使用 boost::any 的類。您可以從成員函數(shù) value() 中獲取類型為 boost::any 的對象。

示例 63.1 調(diào)用 as(),而不是 value()。此成員函數(shù)將命令行選項的值轉(zhuǎn)換為作為模板參數(shù)傳遞的類型。 as() 使用 boost::any_cast() 進(jìn)行類型轉(zhuǎn)換。

確保您傳遞給 as() 的類型與命令行選項的類型相匹配。例如,示例 63.1 期望將命令行選項 --age 設(shè)置為 int 類型的數(shù)字,因此必須將 int 作為模板參數(shù)傳遞給 as()。

您可以通過多種方式啟動示例 63.1。這是一個例子:

測試

在這種情況下,顯示 Pi: 3.14。因為 --pi 未在命令行上設(shè)置,所以顯示默認(rèn)值。

此示例使用 --pi 設(shè)置一個值:

測試 --pi 3.1415

該程序現(xiàn)在顯示 Pi:3.1415。

這個例子也傳遞了一個年齡:

測試 --pi 3.1415 --age 29

輸出現(xiàn)在是 On age: 29 和 Age: 29。第一行是在調(diào)用 boost::program_options::notify() 時寫入的;這會觸發(fā) on_age() 的執(zhí)行。 --pi 沒有輸出,因為程序使用 else if 語句,如果未設(shè)置 --age 則僅顯示用 --pi 設(shè)置的值。

此示例顯示幫助:

測試 -h

您可以獲得所有命令行選項的完整概述:

Options: -h [ --help ]         Help screen --pi arg (=3.1400001) Pi --age arg             Age

如您所見,幫助可以以兩種不同的方式顯示,因為為該命令行選項定義了一個短名稱。對于 --pi,顯示默認(rèn)值。命令行選項及其描述會自動格式化。您只需將類型為 boost::program_options::options_description 的對象寫入標(biāo)準(zhǔn)輸出,如示例 63.1 所示。

現(xiàn)在,像這樣開始這個例子:

測試——年齡

輸出如下:

缺少選項“--age”所需的參數(shù)。

因為未設(shè)置 --age,boost::program_options::parse_command_line() 中使用的解析器會拋出 boost::program_options::error 類型的異常。捕獲異常,并將錯誤消息寫入標(biāo)準(zhǔn)輸出。

boost::program_options::error 派生自 std::logic_error。 Boost.ProgramOptions 定義了額外的異常,它們都派生自 boost::program_options::error。其中一個異常是 boost::program_options::invalid_syntax,如果您沒有為 --age 提供值,它就是在示例 63.1 中拋出的異常。

示例 63.2 引入了更多可用于 Boost.ProgramOptions 的配置設(shè)置。

示例 63.2。使用 Boost.ProgramOptions 的特殊配置設(shè)置

#include <boost/program_options.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace boost::program_options;
void to_cout(const std::vector<std::string> &v)
{
  std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>{
    std::cout, "\n"});
}
int main(int argc, const char *argv[])
{
  try
  {
    int age;
    options_description desc{"Options"};
    desc.add_options()
      ("help,h", "Help screen")
      ("pi", value<float>()->implicit_value(3.14f), "Pi")
      ("age", value<int>(&age), "Age")
      ("phone", value<std::vector<std::string>>()->multitoken()->
        zero_tokens()->composing(), "Phone")
      ("unreg", "Unrecognized options");
    command_line_parser parser{argc, argv};
    parser.options(desc).allow_unregistered().style(
      command_line_style::default_style |
      command_line_style::allow_slash_for_short);
    parsed_options parsed_options = parser.run();
    variables_map vm;
    store(parsed_options, vm);
    notify(vm);
    if (vm.count("help"))
      std::cout << desc << '\n';
    else if (vm.count("age"))
      std::cout << "Age: " << age << '\n';
    else if (vm.count("phone"))
      to_cout(vm["phone"].as<std::vector<std::string>>());
    else if (vm.count("unreg"))
      to_cout(collect_unrecognized(parsed_options.options,
        exclude_positional));
    else if (vm.count("pi"))
      std::cout << "Pi: " << vm["pi"].as<float>() << '\n';
  }
  catch (const error &ex)
  {
    std::cerr << ex.what() << '\n';
  }
}

Example 63.2

設(shè)置配置后,在解析器上調(diào)用 run()。此成員函數(shù)在 boost::program_options::parsed_options 類型的對象中返回解析的命令行選項,您可以將其傳遞給 boost::program_options::store() 以將選項存儲在 vm 中。

在代碼的后面,示例 63.2 再次訪問 vm 以評估命令行選項。只有對 boost::program_options::collect_unrecognized() 的調(diào)用是新的。此函數(shù)為命令行選項 --unreg 調(diào)用。該函數(shù)需要一個 boost::program_options::parsed_options 類型的對象,它由 run() 返回。它在 std::vector<std::string> 中返回所有未知的命令行選項。例如,如果您使用 test --unreg --abc 啟動程序,--abc 將寫入標(biāo)準(zhǔn)輸出。

當(dāng) boost::program_options::exclude_positional 作為第二個參數(shù)傳遞給 boost::program_options::collect_unrecognized() 時,位置選項將被忽略。對于示例 63.2,這無關(guān)緊要,因為沒有定義位置選項。但是,boost::program_options::collect_unrecognized() 需要此參數(shù)。

示例 63.3 說明了位置選項。

示例 63.3。 Boost.ProgramOptions 的位置選項

#include <boost/program_options.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace boost::program_options;
void to_cout(const std::vector<std::string> &v)
{
  std::copy(v.begin(), v.end(),
    std::ostream_iterator<std::string>{std::cout, "\n"});
}
int main(int argc, const char *argv[])
{
  try
  {
    options_description desc{"Options"};
    desc.add_options()
      ("help,h", "Help screen")
      ("phone", value<std::vector<std::string>>()->
        multitoken()->zero_tokens()->composing(), "Phone");
    positional_options_description pos_desc;
    pos_desc.add("phone", -1);
    command_line_parser parser{argc, argv};
    parser.options(desc).positional(pos_desc).allow_unregistered();
    parsed_options parsed_options = parser.run();
    variables_map vm;
    store(parsed_options, vm);
    notify(vm);
    if (vm.count("help"))
      std::cout << desc << '\n';
    else if (vm.count("phone"))
      to_cout(vm["phone"].as<std::vector<std::string>>());
  }
  catch (const error &ex)
  {
    std::cerr << ex.what() << '\n';
  }
}

Example 63.3 

示例 63.3 使用類 boost::program_options::positional_options_description 將 --phone 定義為位置選項。此類提供成員函數(shù) add(),它需要傳遞命令行選項的名稱和位置。該示例傳遞“phone”和 -1。

使用位置選項,可以在命令行上設(shè)置值,而無需使用命令行選項。您可以像這樣啟動示例 63.3:

測試 123 456

即使未使用 --phone,123 和 456 也會被識別為電話號碼。

在類型為 boost::program_options::positional_options_description 的對象上調(diào)用 add() 會將命令行上的值分配給使用位置編號的命令行選項。當(dāng)使用命令行測試 123 456 調(diào)用示例 63.3 時,123 的位置編號為 0,456 的位置編號為 1。示例 63.3 將 -1 傳遞給 add(),它將所有值 - 123 和 456 - 分配給 - -電話。如果您更改示例 63.3 以將值 0 傳遞給 add(),則只有 123 會被識別為電話號碼。如果將 1 傳遞給 add(),則只會識別 456。

pos_desc 與 positional() 一起傳遞給解析器。這就是解析器如何知道哪些命令行選項是位置的。

請注意,您必須確保定義了位置選項。例如,在示例 63.3 中,“phone”只能傳遞給 add(),因為 --phone 的定義已經(jīng)存在于 desc 中。

在之前的所有示例中,Boost.ProgramOptions 用于解析命令行選項。但是,該庫也支持從文件加載配置選項。如果必須重復(fù)設(shè)置相同的命令行選項,這會很有用。

示例 63.4。從配置文件加載選項

#include <boost/program_options.hpp>
#include <string>
#include <fstream>
#include <iostream>
using namespace boost::program_options;
int main(int argc, const char *argv[])
{
  try
  {
    options_description generalOptions{"General"};
    generalOptions.add_options()
      ("help,h", "Help screen")
      ("config", value<std::string>(), "Config file");
    options_description fileOptions{"File"};
    fileOptions.add_options()
      ("age", value<int>(), "Age");
    variables_map vm;
    store(parse_command_line(argc, argv, generalOptions), vm);
    if (vm.count("config"))
    {
      std::ifstream ifs{vm["config"].as<std::string>().c_str()};
      if (ifs)
        store(parse_config_file(ifs, fileOptions), vm);
    }
    notify(vm);
    if (vm.count("help"))
      std::cout << generalOptions << '\n';
    else if (vm.count("age"))
      std::cout << "Your age is: " << vm["age"].as<int>() << '\n';
  }
  catch (const error &ex)
  {
    std::cerr << ex.what() << '\n';
  }
}

Example 63.4 

示例 63.4 使用了兩個類型為 boost::program_options::options_description 的對象。 generalOptions 定義必須在命令行上設(shè)置的選項。 fileOptions 定義可以從配置文件加載的選項。

不必使用類型為 boost::program_options::options_description 的兩個不同對象來定義選項。如果命令行和文件的選項集相同,則可以只使用一個。在示例 63.4 中,分隔選項是有意義的,因為您不想允許在配置文件中設(shè)置 --help。如果允許并且用戶將該選項放入配置文件中,則程序每次都會顯示幫助屏幕。

示例 63.4 從配置文件加載 --age。您可以將配置文件的名稱作為命令行選項傳遞。出于這個原因,在此示例中,--config 是在 generalOptions 中定義的。

在使用 boost::program_options::parse_command_line() 解析命令行選項并存儲在 vm 中后,該示例檢查是否設(shè)置了 --config。如果是,則使用 std::ifstream 打開配置文件。 std::ifstream 對象與描述選項的文件選項一起傳遞給函數(shù) boost::program_options::parse_config_file()。 boost::program_options::parse_config_file() 做與 boost::program_options::parse_command_line() 相同的事情,并在 boost::program_options::parsed_options 類型的對象中返回解析后的選項。該對象被傳遞給 boost::program_options::store() 以將解析的選項存儲在 vm 中。

如果您創(chuàng)建一個名為 config.txt 的文件,將 age=29 放入該文件,然后執(zhí)行下面的命令行,您將得到顯示的結(jié)果。

測試 --config config.txt

輸出如下:

Your age is: 29

如果您在命令行和配置文件中支持相同的選項,您的程序可能會解析相同的選項兩次——一次使用 boost::program_options::parse_command_line(),一次使用 boost::program_options::parse_config_file()。函數(shù)調(diào)用的順序決定了您將在 vm 中找到哪個值。一旦命令行選項的值存儲在 vm 中,該值將不會被覆蓋。該值是由命令行上的選項還是在配置文件中設(shè)置的,僅取決于您調(diào)用 store() 函數(shù)的順序。

Boost.ProgramOptions 還定義了函數(shù) boost::program_options::parse_environment(),可用于從環(huán)境變量加載選項。類 boost::environment_iterator 允許您迭代環(huán)境變量。

到此這篇關(guān)于C++ Boost ProgramOptions超詳細(xì)講解的文章就介紹到這了,更多相關(guān)C++ Boost ProgramOptions內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C語言中rand函數(shù)的使用

    詳解C語言中rand函數(shù)的使用

    在編程時我們有時總希望自己產(chǎn)生一個隨機數(shù)字,以供使用,那么下面介紹rand函數(shù)的使用,有需要的可以參考學(xué)習(xí)。
    2016-08-08
  • C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解

    C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解

    這篇文章主要介紹了C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解,需要的朋友可以參考下
    2018-03-03
  • C語言指針超詳細(xì)講解下篇

    C語言指針超詳細(xì)講解下篇

    指針提供了對地址操作的一種方法,因此,使用指針可使得?C?語言能夠更高效地實現(xiàn)對計算機底層硬件的操作。另外,通過指針可以更便捷地操作數(shù)組。在一定意義上可以說,指針是?C?語言的精髓
    2022-04-04
  • C++ explicit關(guān)鍵字講解

    C++ explicit關(guān)鍵字講解

    這篇文章主要介紹了C++ explicit關(guān)鍵字講解,++提供了explicit關(guān)鍵字,相對于implicit而言,他默認(rèn)關(guān)閉了隱式類型轉(zhuǎn)換方法。至于兩者有什么區(qū)別,看下面文章內(nèi)容的介紹吧
    2021-12-12
  • Vs?Code中C/C++配置launch.json和tasks.json文件詳細(xì)步驟

    Vs?Code中C/C++配置launch.json和tasks.json文件詳細(xì)步驟

    使用VSCode開發(fā)C/C++程序,需要配置tasks.json/launch.json,下面這篇文章主要給大家介紹了關(guān)于Vs?Code中C/C++配置launch.json和tasks.json文件的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • 用C# 控制Windows系統(tǒng)音量的實現(xiàn)方法

    用C# 控制Windows系統(tǒng)音量的實現(xiàn)方法

    本篇文章是對使用C#控制Windows系統(tǒng)音量的實現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言尋找無向圖兩點間的最短路徑

    C語言尋找無向圖兩點間的最短路徑

    這篇文章主要為大家詳細(xì)介紹了C語言尋找無向圖兩點間的最短路徑,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言之函數(shù)返回值與參數(shù)傳遞案例教程

    C語言之函數(shù)返回值與參數(shù)傳遞案例教程

    這篇文章主要介紹了C語言之函數(shù)返回值與參數(shù)傳遞案例教程,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++入門到精通之循環(huán)語句的使用教程

    C++入門到精通之循環(huán)語句的使用教程

    這篇文章主要給大家介紹了關(guān)于C++中循環(huán)語句的用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C++?Boost?Lambda表達(dá)式詳解

    C++?Boost?Lambda表達(dá)式詳解

    Lambda?表達(dá)式(lambda?expression)是一個匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。本文就來為大家詳細(xì)講講C++中Lambda表達(dá)式的使用,需要的可以參考一下
    2022-11-11

最新評論