最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

4.9 C++ Boost 命令行解析庫(kù)

2023-08-31 13:00 作者:bili_42682284418  | 我要投稿

命令行解析庫(kù)是一種用于簡(jiǎn)化處理命令行參數(shù)的工具,它可以幫助開(kāi)發(fā)者更方便地解析命令行參數(shù)并提供適當(dāng)?shù)膸椭畔?。C++語(yǔ)言中,常用的命令行解析庫(kù)有許多,通過(guò)本文的學(xué)習(xí),讀者可以了解不同的命令行解析庫(kù)和它們?cè)贑++項(xiàng)目中的應(yīng)用,從而更加靈活和高效地處理命令行參數(shù)。

一般比較常見(jiàn)的解析庫(kù):

  • ??getopt:一個(gè)C語(yǔ)言的命令行解析庫(kù),也被廣泛用于C++程序。它提供了一組函數(shù)來(lái)解析命令行參數(shù),并支持短選項(xiàng)(如 -a)和長(zhǎng)選項(xiàng)(如 --help)。

  • ??Boost.Program_options:這是Boost庫(kù)中的一個(gè)模塊,提供了一個(gè)強(qiáng)大的命令行解析庫(kù)。它支持短選項(xiàng)、長(zhǎng)選項(xiàng)、位置參數(shù)等,并且具有很好的錯(cuò)誤處理和幫助信息生成功能。

  • ??TCLAP:TCLAP(Templatized C++ Command Line Parser Library)是一個(gè)C++的命令行解析庫(kù),它提供了簡(jiǎn)單易用的API來(lái)解析命令行參數(shù),并支持短選項(xiàng)和長(zhǎng)選項(xiàng)。

  • ??CLI11:CLI11是一個(gè)現(xiàn)代化的C++命令行解析庫(kù),它使用C++11標(biāo)準(zhǔn),并提供了一組簡(jiǎn)單易用的API。

這些庫(kù)各有特點(diǎn),開(kāi)發(fā)者可以根據(jù)項(xiàng)目的需求和個(gè)人喜好選擇合適的命令行解析庫(kù)。通過(guò)使用這些庫(kù),開(kāi)發(fā)者可以更輕松地處理命令行參數(shù),提高程序的易用性和用戶(hù)體驗(yàn)。在命令行程序中,argc和argv是C++程序中用于接收命令行參數(shù)的主要機(jī)制。其中:

  • ??argc(Argument Count)表示命令行參數(shù)的個(gè)數(shù),包括程序本身。至少為1,即程序名。

  • ??argv(Argument Vector)是一個(gè)指向字符指針數(shù)組的指針,每個(gè)指針指向一個(gè)以空字符結(jié)尾的C字符串,表示一個(gè)命令行參數(shù)。

通常,argv[0]?存儲(chǔ)的是程序的名稱(chēng),argv[1]?開(kāi)始存儲(chǔ)的是傳遞給程序的實(shí)際命令行參數(shù)。開(kāi)發(fā)者可以通過(guò)對(duì)?argc?和?argv?的處理,來(lái)獲取和解析命令行參數(shù),從而完成特定功能的配置和操作。例如,使用?getoptBoost.Program_options?或者其他命令行解析庫(kù)來(lái)解析和處理命令行參數(shù),更方便地獲取用戶(hù)的輸入。

9.1 在字符串上解析

該段代碼通過(guò)簡(jiǎn)單的字符串切割實(shí)現(xiàn)了對(duì)命令行參數(shù)的解析。它將命令行字符串切割為選項(xiàng)和參數(shù),并輸出它們的內(nèi)容。同時(shí),根據(jù)特定的選項(xiàng)和參數(shù)組合條件,輸出用戶(hù)登錄的相關(guān)信息。

代碼的主要流程如下:

  1. 1.?定義了一個(gè)函數(shù)?GetOpt,該函數(shù)接收一個(gè)字符指針?command(命令行字符串)和一個(gè)二維字符數(shù)組?command_ptr(用于存儲(chǔ)解析后的選項(xiàng)和參數(shù))。

  2. 2.?在?GetOpt?函數(shù)中,使用?strtok?函數(shù)對(duì)?command?字符串進(jìn)行切割和解析,將選項(xiàng)和參數(shù)存儲(chǔ)在?command_ptr?數(shù)組中,并返回選項(xiàng)和參數(shù)的總數(shù)。

  3. 3.?在?main()?函數(shù)中,構(gòu)造一個(gè)命令行字符串?cmd,然后調(diào)用?GetOpt?函數(shù),將解析后的選項(xiàng)和參數(shù)存儲(chǔ)在?Opts?數(shù)組中,并獲取選項(xiàng)和參數(shù)的總數(shù)?count。

  4. 4.?使用?for?循環(huán)遍歷?Opts?數(shù)組,根據(jù)數(shù)組索引的奇偶性分別輸出命令行選項(xiàng)和參數(shù)。

讀者需要注意,此代碼使用簡(jiǎn)單的字符串切割來(lái)實(shí)現(xiàn)命令行參數(shù)的解析,并假設(shè)輸入的命令行格式是固定的,即選項(xiàng)和參數(shù)的順序和格式是固定的(如 "--address 127.0.0.1 --password 123456 --port 22")。如果輸入的命令行格式有變化或者更復(fù)雜的需求,可能需要使用更強(qiáng)大的命令行解析庫(kù)來(lái)完成更靈活的解析工作。

#include?<iostream>
#include?<Windows.h>

using?namespace?std;

//?傳入命令行,切割解析
int?GetOpt(IN?char?*command,?OUT?char?command_ptr[][1024])
{
????char*?ptr;

????ptr?=?strtok(command,?"?");
????int?count?=?0;

????while?(ptr?!=?NULL)
????{
????????strcpy(command_ptr[count++],?ptr);
????????ptr?=?strtok(NULL,?"?");
????}
????return?count;
}

int?main(int?argc,?char*?argv[])
{
????char?cmd[4096]?=?"--address?127.0.0.1?--password?123456?--port?22";
????char?Opts[30][1024];

????int?count?=?GetOpt(cmd,?Opts);
????for?(int?x?=?0;?x?<?count;?x++)
????{
????????if?(x?%?2?==?0)
????????{
????????????std::cout?<<?"命令行:?"?<<?Opts[x]?<<?std::endl;
????????}
????????else
????????{
????????????std::cout?<<?"參數(shù):?"?<<?Opts[x]?<<?std::endl;
????????}
????}

????//?參數(shù)解析使用
????if?((strcmp(Opts[0],?"--address")?==?0)?&&?(strcmp(Opts[2],?"--password")?==?0)?&&?(strcmp(Opts[4],?"--port")?==?0))
????{
????????std::cout?<<?"用戶(hù)登錄:?"?<<?Opts[1]?<<?"?密碼:?"?<<?Opts[3]?<<?"?端口:?"?<<?Opts[5]?<<?std::endl;
????}
????return?0;
}

9.2 自實(shí)現(xiàn)參數(shù)解析

這段代碼是筆者突發(fā)奇想之后寫(xiě)出來(lái)的一個(gè)簡(jiǎn)易版參數(shù)解析器,通過(guò)檢查參數(shù)個(gè)數(shù)和特定的選項(xiàng)和參數(shù)組合,輸出對(duì)應(yīng)的類(lèi)型、地址和端口信息。如果參數(shù)個(gè)數(shù)小于等于2,則輸出使用說(shuō)明;如果參數(shù)個(gè)數(shù)等于7且滿(mǎn)足特定格式 "--type tcp/udp --address 127.0.0.1 --port 8888",則輸出用戶(hù)指定的類(lèi)型、地址和端口信息。

代碼的主要流程如下:

  1. 1.?通過(guò)檢查?argc?的值,如果小于等于2,則輸出使用說(shuō)明提示用戶(hù)正確輸入命令行參數(shù)。

  2. 2.?如果參數(shù)個(gè)數(shù)等于7,按照特定的格式 "--type tcp/udp --address 127.0.0.1 --port 8888" 進(jìn)行解析和判斷。

  3. 3.?使用?strcmp?函數(shù)判斷命令行選項(xiàng)是否為 "--type"、"--address" 和 "--port",并檢查其后的參數(shù)是否符合預(yù)期格式。

根據(jù)特定的選項(xiàng)和參數(shù)組合條件,輸出對(duì)應(yīng)的類(lèi)型、地址和端口信息。

#include?<Windows.h>
#include?<iostream>

int?main(int?argc,?char*?argv[])
{
????//?如果小于兩個(gè)參數(shù)則輸出提示
????if?(argc?<=?2)
????{
????????fprintf(stderr,?"\nUsage:\n\n"
????????????"?\t?--type??????????????指定類(lèi)型(string)?\n"
????????????"?\t?--address???????????指定地址(string)?\n"
????????????"?\t?--port??????????????指定端口(int)????\n\n"
????????);
????????exit(0);
????}

????//?如果參數(shù)個(gè)數(shù)是7那么總共需要有6個(gè)參數(shù)傳遞
????//?其中?1,3,5?代表的是參數(shù)開(kāi)關(guān)
????//?剩余?2,4,6?則代表每個(gè)開(kāi)關(guān)傳入?yún)?shù)
????if?(argc?==?7)
????{
????????//?--type?tcp/udp?--address?127.0.0.1?--port?8888
????????if?(strcmp((char*)argv[1],?"--type")?==?0?&&?strcmp((char*)argv[3],?"--address")?==?0?&&?strcmp((char*)argv[5],?"--port")?==?0?)
????????{
????????????//?開(kāi)關(guān)內(nèi)部,也可以嵌套繼續(xù)判斷類(lèi)型
????????????if?(strcmp((char*)argv[2],?"tcp")?==?0)
????????????{
????????????????printf("[+]?類(lèi)型:?%s?地址:?%s?端口:?%d?\n",?argv[2],?argv[4],?atoi(argv[6]));
????????????}
????????????else?if?(strcmp((char*)argv[2],?"udp")?==?0)
????????????{
????????????????printf("[+]?類(lèi)型:?%s?地址:?%s?端口:?%d?\n",?argv[2],?argv[4],?atoi(argv[6]));
????????????}
????????}
????}
????return?0;
}

如上代碼所示,是筆者最常用的命令行解析方式,這種方式比較死板無(wú)法更智能的判斷參數(shù)類(lèi)型,如果需要判斷的更全面則需要將其改進(jìn)為以下格式,改進(jìn)后雖然解析更靈活了,但管理起來(lái)也會(huì)變得更復(fù)雜。

如下所示,代碼實(shí)現(xiàn)了一個(gè)32位端口快速掃描器的簡(jiǎn)單功能。通過(guò)解析命令行參數(shù),用戶(hù)可以指定待掃描的IP地址、開(kāi)始端口和結(jié)束端口,并根據(jù)參數(shù)選擇相應(yīng)的掃描方式。如果沒(méi)有指定合法的參數(shù)或缺少必要參數(shù),則輸出工具的菜單選項(xiàng)供用戶(hù)參考。

代碼的主要流程如下:

  1. 1.?定義了一個(gè)結(jié)構(gòu)體?GetOpt?用于保存參數(shù)信息,并定義了全局變量?opt?作為全局參數(shù)存儲(chǔ)對(duì)象。

  2. 2.?編寫(xiě)函數(shù)?getOpts?對(duì)命令行參數(shù)進(jìn)行解析,并將解析結(jié)果存儲(chǔ)到結(jié)構(gòu)體?opt?中。

  3. 3.?編寫(xiě)函數(shù)?ShowOptions?輸出工具的菜單選項(xiàng),包含待掃描的IP地址、開(kāi)始端口和結(jié)束端口的參數(shù)說(shuō)明。

在?main()?函數(shù)中,根據(jù)命令行參數(shù)的解析結(jié)果,輸出對(duì)應(yīng)的信息:如果同時(shí)指定了IP地址、開(kāi)始端口和結(jié)束端口,則輸出對(duì)應(yīng)的掃描信息;如果只指定了開(kāi)始端口和結(jié)束端口,則輸出端口范圍信息;否則,顯示工具的菜單選項(xiàng)。

#define?_CRT_SECURE_NO_WARNINGS
#include?<stdio.h>
#include?<Windows.h>

typedef?struct?GetOpt????//?全局保存每個(gè)參數(shù)
{

??char?Address[128];???//?IP地址
??int?Start;???????????//?開(kāi)始端口
??int?End;?????????????//?結(jié)束端口
}GetOpt;

static?struct?GetOpt?opt;?//?定義全局結(jié)構(gòu)體

//?getOpts?針對(duì)參數(shù)的解析與賦值
int?getOpts(int?argc,?char?**argv)
{
??strcpy(opt.Address,?"null");???//?初始化參數(shù)解析
??opt.Start?=?0;?opt.End?=?0;????//?初始化參數(shù)解析

??for?(int?each?=?1;?each?<?argc;?each++)
??{
????if?(!strcmp(argv[each],?"--addr")?&&?each?+?1?<?argc)
????{
??????strcpy(opt.Address,?argv[++each]);
????}
????else?if?(!strcmp(argv[each],?"--start")?&&?each?+?1?<?argc)
????{
??????opt.Start?=?atoi(argv[++each]);
????}
????else?if?(!strcmp(argv[each],?"--end")?&&?each?+?1?<?argc)
????{
??????opt.End?=?atoi(argv[++each]);
????}
????else?{?return?0;?}
??}
??return?1;
}

//?輸出工具菜單選項(xiàng)
void?ShowOptions()
{
??fprintf(stderr,?"\n"
????"Usage:?32位端口快速掃描器?Ver:1.0??By:Lyshark?\n\n"
????"options:?\n"
????"\t?--addr?[addr]??????指定待掃描的Ip地址?\n"
????"\t?--start?[count]????指定待掃描的開(kāi)始端口?\n"
????"\t?--end?[count]??????指定待掃描的結(jié)束端口?\n"
????);
}

//?主函數(shù)還是用來(lái)判斷參數(shù),并執(zhí)行相應(yīng)的命令
int?main(int?argc,?char*?argv[])
{
??if?(getOpts(argc,?argv)?!=?1)
??{
????ShowOptions();
??}
??else?if?(strcmp(opt.Address,?"null")?!=?0?&&?opt.Start?!=?0?&&?opt.End?!=?0)
??{
????for?(int?x?=?0;?x?<?100;?x++)
??????printf("掃描:?%s?開(kāi)始地址:?%d?結(jié)束地址:?%d?\n",?opt.Address,?x,?opt.End);
??}
??else?if?(opt.Start?!=?0?&&?opt.End?!=?0)
??{
????for?(int?y?=?0;?y?<?10;?y++)
??????printf("端口范圍:?%d?->?%d?\n",?y,?opt.End);
??}
??else?{?ShowOptions();?}

??return?0;
}

9.3 交互式參數(shù)解析

交互式參數(shù)解析器,其實(shí)就是類(lèi)似于Linux系統(tǒng)終端那樣的頁(yè)面,運(yùn)行代碼后進(jìn)入一個(gè)可交互環(huán)境,讀者可以執(zhí)行需要的命令。該功能的實(shí)現(xiàn)依賴(lài)于tokenizer.hpp模塊,該模塊提供了靈活、高效的字符串分割工具,可以幫助簡(jiǎn)化字符串處理的任務(wù),特別是在文本處理、配置文件解析、數(shù)據(jù)解析等方面有著廣泛的應(yīng)用。

boost/tokenizer.hpp?主要功能是將一個(gè)字符串拆分成多個(gè)子串(tokens),通過(guò)指定分隔符或者符合某種條件的位置來(lái)實(shí)現(xiàn)字符串的分割。這在處理文本文件、解析命令行參數(shù)、數(shù)據(jù)處理等方面非常有用。

使用?boost::tokenizer?需要包含?<boost/tokenizer.hpp>?頭文件,并在代碼中使用?boost::tokenizer?類(lèi)的實(shí)例對(duì)象來(lái)進(jìn)行字符串的分割。該類(lèi)提供了靈活的選項(xiàng),允許用戶(hù)指定分隔符、忽略空白字符、指定分隔符類(lèi)型等。

例如,下面是一個(gè)使用?boost::tokenizer?進(jìn)行字符串分割的簡(jiǎn)單示例:

#include?<iostream>
#include?<string>
#include?<boost/tokenizer.hpp>

int?main()
{
????std::string?input?=?"Boost?C++?Libraries";
????boost::tokenizer<>?tokens(input);?//?默認(rèn)使用空格作為分隔符

????for?(const?auto&?token?:?tokens)?{
????????std::cout?<<?token?<<?std::endl;
????}

????return?0;
}

上述示例會(huì)將字符串?"Boost C++ Libraries"?按照空格進(jìn)行分割,并輸出拆分得到的子串。運(yùn)用此功能并配合一個(gè)死循環(huán)結(jié)構(gòu)我們就可以構(gòu)建出一個(gè)交互式命令行環(huán)境,并可以根據(jù)用戶(hù)輸入的命令執(zhí)行相應(yīng)的操作。

根據(jù)上述所示的庫(kù)函數(shù),我們可以靈活的實(shí)現(xiàn)參數(shù)的解析功能,并實(shí)現(xiàn)一個(gè)簡(jiǎn)單的交互式參數(shù)解析功能,如下所示將提供三個(gè)交互命令,讀者可自行編譯并運(yùn)行測(cè)試。

代碼的主要流程如下:

  1. 1.?使用?std::getline(std::cin, command)?從標(biāo)準(zhǔn)輸入讀取用戶(hù)輸入的命令,并將命令存儲(chǔ)在字符串?command?中。

  2. 2.?通過(guò)字符串的比較判斷用戶(hù)輸入的命令,如果是 "help" 則輸出功能菜單,展示可用的命令選項(xiàng)。

  3. 3.?使用?boost::tokenizer?將用戶(hù)輸入的命令進(jìn)行分割,提取出命令關(guān)鍵詞和參數(shù)。

  4. 4.?根據(jù)分割后的命令關(guān)鍵詞和參數(shù),執(zhí)行相應(yīng)的功能:

    • ??如果是 "AddRule" 命令,則解析地址和DNS參數(shù),并輸出解析結(jié)果。

    • ??如果是 "DeleteRule" 命令,則解析地址參數(shù),并輸出刪除地址信息。

    • ??如果是 "ShowList" 命令,則輸出一個(gè)簡(jiǎn)單的數(shù)字列表。

#include?<iostream>
#include?<string>
#include?<boost/tokenizer.hpp>

using?namespace?std;
using?namespace?boost;

int?main(int?argc,?char?const?*argv[])
{
??std::string?command;

??while?(1)
??{
????std::cout?<<?"[LyShark]?#?";
????std::getline(std::cin,command);

????if?(command.length()?==?0)
????{
??????continue;
????}
????else?if?(command?==?"help")
????{
??????std::cout?<<?"[功能菜單]?\n"?<<?std::endl;
??????std::cout?<<?"增加規(guī)則:?AddRule?--address?192.168.1.1?--dns?8.8.8.8"?<<?std::endl;
??????std::cout?<<?"刪除規(guī)則:?DeleteRule?--address?192.168.1.1"?<<?std::endl;
??????std::cout?<<?"輸出列表:?ShowList"?<<?std::endl;
????}
????else
????{
??????//?定義分詞器:?定義分割符號(hào)為[逗號(hào),空格]
??????boost::char_separator<char>?sep(",?--");
??????typedef?boost::tokenizer<boost::char_separator<char>>?CustonTokenizer;
??????CustonTokenizer?tok(command,?sep);

??????//?將分詞結(jié)果放入vector鏈表
??????std::vector<std::string>?vecSegTag;
??????for?(CustonTokenizer::iterator?beg?=?tok.begin();?beg?!=?tok.end();?++beg)
??????{
????????vecSegTag.push_back(*beg);
??????}

??????//?解析?[shell]?#?AddRule?--address?192.168.1.1?--dns?8.8.8.8
??????if?(vecSegTag.size()?==?5?&&?vecSegTag[0]?==?"AddRule")
??????{
????????if?(vecSegTag[1]?==?"address"?&&?vecSegTag[3]?==?"dns")
????????{
??????????std::string?set_address?=?vecSegTag[2];
??????????std::string?set_dns?=?vecSegTag[4];
??????????std::cout?<<?"解析地址:?"?<<?vecSegTag[2]?<<?"解析DNS:?"?<<?vecSegTag[4]?<<?std::endl;
????????}
??????}
??????//?解析?[shell]?#?DeleteRule?--address?192.168.1.1
??????else?if?(vecSegTag.size()?==?3?&&?vecSegTag[0]?==?"DeleteRule")
??????{
????????if?(vecSegTag[1]?==?"address")
????????{
??????????std::string?del_address?=?vecSegTag[2];
??????????std::cout?<<?"刪除地址:?"?<<?del_address?<<?std::endl;
????????}
??????}
??????//?解析?[shell]?#?ShowList
??????else?if?(vecSegTag.size()?==?1?&&?vecSegTag[0]?==?"ShowList")
??????{
????????for?(int?x?=?0;?x?<?10;?x++)
????????{
??????????std::cout?<<?x?<<?std::endl;
????????}
??????}
????}
??}
??return?0;
}

9.4 非交互參數(shù)解析

雖然分詞器可以用于參數(shù)解析,但是其本身并不是用于做參數(shù)解析用的,在Boost中提供了Boost.Program_options庫(kù),該框架提供了強(qiáng)大而靈活的命令行選項(xiàng)解析功能,可以幫助簡(jiǎn)化處理命令行參數(shù)的過(guò)程,并提供良好的幫助信息和錯(cuò)誤處理機(jī)制,是處理命令行參數(shù)的優(yōu)秀工具庫(kù)之一。

使用?Boost.Program_options?需要包含?<boost/program_options.hpp>?頭文件,并通過(guò)創(chuàng)建?boost::program_options::options_description?對(duì)象來(lái)定義選項(xiàng)描述,然后使用?boost::program_options::parse_command_line?函數(shù)解析命令行參數(shù),最后通過(guò)?boost::program_options::variables_map?對(duì)象獲取解析后的選項(xiàng)和參數(shù)的值。

例如,下面是一個(gè)使用?Boost.Program_options?解析命令行參數(shù)的簡(jiǎn)單示例:

代碼的主要流程如下:

  1. 1.?使用?boost::program_options::options_description?定義命令行選項(xiàng)描述,包含三個(gè)選項(xiàng):address、start_port?和?end_port,以及一個(gè)?help?選項(xiàng)用于輸出幫助菜單。

  2. 2.?使用?boost::program_options::parse_command_line?函數(shù)解析命令行參數(shù),并將解析結(jié)果存儲(chǔ)在?boost::program_options::variables_map?對(duì)象?virtual_map?中。

  3. 3.?使用?boost::program_options::notify?函數(shù)檢查命令行參數(shù)是否符合預(yù)期,并存儲(chǔ)解析后的值到?virtual_map

  4. 4.?根據(jù)?virtual_map中存儲(chǔ)的命令行參數(shù)值,判斷用戶(hù)輸入的選項(xiàng)并執(zhí)行相應(yīng)的操作:

    • ??如果用戶(hù)輸入了?--help?或?-h?選項(xiàng),則輸出幫助菜單。

    • ??如果用戶(hù)輸入了?--address--start_port?和?--end_port?選項(xiàng),則輸出掃描地址、開(kāi)始端口和結(jié)束端口的信息。

    • ??如果用戶(hù)輸入了未定義的選項(xiàng)或缺少必需的選項(xiàng),則輸出參數(shù)錯(cuò)誤信息。

通過(guò)使用?Boost.Program_options?庫(kù),可以更方便地定義和解析命令行選項(xiàng),從而使程序的命令行使用更加友好和靈活。

#include?<iostream>
#include?<boost/program_options.hpp>

namespace?opt?=?boost::program_options;

int?main(int?argc,?char?const?*argv[])
{
??opt::options_description?des_cmd("\n?Usage:?32位端口快速掃描器?Ver:1.0?\n\n?Options");
??des_cmd.add_options()
????("address,a",?opt::value<std::string>()->default_value("127.0.0.1"),?"指定掃描地址")
????("start_port,s",?opt::value<int>()->default_value(0),?"掃描開(kāi)始端口")
????("end_port,e",?opt::value<int>()->default_value(65535),?"掃描結(jié)束端口")
????("help,h",?"幫助菜單");

??opt::variables_map?virtual_map;
??try
??{
????opt::store(opt::parse_command_line(argc,?argv,?des_cmd),?virtual_map);
??}
??catch?(...){?return?0;?}

??//?定義消息
??opt::notify(virtual_map);

??//?無(wú)參數(shù)直接返回
??if?(virtual_map.empty())
??{
????return?0;
??}
??else?if?(virtual_map.count("help")?||?virtual_map.count("h"))
??{
????std::cout?<<?des_cmd?<<?std::endl;
????return?0;
??}
??else?if?(virtual_map.count("address")?&&?virtual_map.count("start_port")?&&?virtual_map.count("end_port"))
??{
????std::string?address?=?virtual_map["address"].as<std::string>();
????int?start_port?=?virtual_map["start_port"].as<int>();
????int?end_port?=?virtual_map["end_port"].as<int>();

????//?判斷是不是默認(rèn)參數(shù)
????if?(?address?==?"127.0.0.1"?||?start_port?==?0?||?end_port?==?65535)
????{
??????std::cout?<<?des_cmd?<<?std::endl;
????}
????else
????{
??????std::cout?<<?"開(kāi)始掃描:?"?<<?address?<<?"?開(kāi)始地址:?"?<<?start_port?<<?"??結(jié)束地址:?"?<<?end_port?<<?std::endl;
????}
??}
??else
??{
????std::cout?<<?"參數(shù)錯(cuò)誤"?<<?std::endl;
??}
??return?0;
}

當(dāng)然了,上述代碼中我們也可以單獨(dú)增加一個(gè)Banner()函數(shù),并將其放入到virtual_map.empty()無(wú)參數(shù)模式,這樣一來(lái)當(dāng)參數(shù)輸入不當(dāng)或無(wú)參數(shù)是則會(huì)打印輸出我們自己的點(diǎn)陣標(biāo)志,能使程序變得更友好。

#include?<iostream>
#include?<boost/program_options.hpp>

namespace?opt?=?boost::program_options;

void?Banner()
{
????printf("?_???????????_????????????????_?????\n");
????printf("|?|_???_?___|?|__???__?_?_?__|?|?__?\n");
????printf("|?|?|?|?/?__|?'_?\\?/?_`?|?'__|?|/?/?\n");
????printf("|?|?|_|?\\__?\\?|?|?|?(_|?|?|??|???<??\n");
????printf("|_|\\__,?|___/_|?|_|\\__,_|_|??|_|\\_\\?\n");
????printf("???|___/????????????????????????????\n\n");
}

int?main(int?argc,?char?const?*argv[])
{
??opt::options_description?des_cmd("\n?Usage:?輸出Logo?Ver:1.0?\n\n?Options");
??des_cmd.add_options()
????("address,a",?opt::value<std::string>(),?"指定掃描地址")
????("start_port,s",?opt::value<int>(),?"掃描開(kāi)始端口")
????("end_port,e",?opt::value<int>(),?"掃描結(jié)束端口")
????("help,h",?"幫助菜單");

??opt::variables_map?virtual_map;
??try
??{
????opt::store(opt::parse_command_line(argc,?argv,?des_cmd),?virtual_map);
??}
??catch?(...){?return?0;?}

??//?定義消息
??opt::notify(virtual_map);

??//?無(wú)參數(shù)直接返回
??if?(virtual_map.empty())
??{
????Banner();
????std::cout?<<?des_cmd?<<?std::endl;
????return?0;
??}
??//?幫助菜單
??else?if?(virtual_map.count("help")?||?virtual_map.count("h"))
??{
????Banner();
????std::cout?<<?des_cmd?<<?std::endl;
????return?0;
??}
??//?分支結(jié)構(gòu)1
??else?if?(virtual_map.count("address")?&&?virtual_map.count("start_port")?&&?virtual_map.count("end_port"))
??{
????std::string?address?=?virtual_map["address"].as<std::string>();
????int?start_port?=?virtual_map["start_port"].as<int>();
????int?end_port?=?virtual_map["end_port"].as<int>();

????std::cout?<<?"開(kāi)始掃描:?"?<<?address?<<?"?開(kāi)始地址:?"?<<?start_port?<<?"??結(jié)束地址:?"?<<?end_port?<<?std::endl;
??}

??//?分支結(jié)構(gòu)2
??else?if?(virtual_map.count("address"))
??{
????std::string?address?=?virtual_map["address"].as<std::string>();
????std::cout?<<?"地址:?"?<<?address?<<?std::endl;
??}

??else
??{
????std::cout?<<?"參數(shù)錯(cuò)誤"?<<?std::endl;
??}
??return?0;
}

本文作者: 王瑞 本文鏈接: https://www.lyshark.com/post/8b095ec4.html 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處!


4.9 C++ Boost 命令行解析庫(kù)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
柳江县| 乃东县| 亳州市| 葫芦岛市| 尉犁县| 吕梁市| 大埔区| 蓝田县| 富顺县| 县级市| 垦利县| 晋城| 敖汉旗| 板桥市| 巨野县| 贡嘎县| 鄂伦春自治旗| 梅州市| 常山县| 改则县| 叶城县| 房产| 布尔津县| 晋江市| 繁昌县| 赣州市| 定陶县| 肇州县| 永丰县| 抚松县| 开化县| 城口县| 通河县| 台北市| 五指山市| 光泽县| 通城县| 清河县| 威海市| 屏南县| 永顺县|