how to use boost program options
From: http://www.radmangames.com/programming/how-to-use-boost-program_options
If it so happens that you’re writing a console application, then chances are you will (or should) want to pass it some parameters at the command line. By default C++ has only the argc and argv parameters to the main function to facilitate this and I can assure you that working with them directly is less than fun. If you have worked with any number of command line programs you would be well aware of a common form that they take and that users expect. To get this expected behavior you should use another favourite boost library of mine: Program options.
Quite simply, Boost.Program_options is the way to do industry standard command line processing in C++, if you’re trying to implement command line arguments in your application then you should be using this library. This tutorial will take you through how to get set up and productive using boost program options with a minimum of fuss.
Obtaining, compiling and linking to boost is not covered.
EDIT: Aug 16 2014
Spurred on by a comment on this post I have written a library that extends Boost.Program_options, providing support for subcommand syntax (think SVN or Mercurial) and including convenient formatting utilities for posix style help output. It's free, open source and awesome! You can check it out here.
Application Template
So you have an program that you want to be able to accept command line parameters? Then replace (or merge) the contents of your main.cpp with the code below. This code forms the foundation of the rest of the tutorial and is boiler plate that you will find yourself writing every time you create a new command line application.
Note: the rest of the examples reference the names of objects in the code below.
#include "boost/program_options.hpp"
#include <iostream>
#include <string>
namespace
{
const size_t ERROR_IN_COMMAND_LINE = 1;
const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // namespace
int main(int argc, char** argv)
{
try
{
/** Define and parse the program options
*/
namespace po = boost::program_options;
po::options_description desc("Options");
desc.add_options()
("help", "Print help messages")
("add", "additional options")
("like", "this");
po::variables_map vm;
try
{
po::store(po::parse_command_line(argc, argv, desc),
vm); // can throw
/** --help option
*/
if ( vm.count("help") )
{
std::cout << "Basic Command Line Parameter App" << std::endl
<< desc << std::endl;
return SUCCESS;
}
po::notify(vm); // throws on error, so do after help in case
// there are any problems
}
catch(po::error& e)
{
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << desc << std::endl;
return ERROR_IN_COMMAND_LINE;
}
// application code here //
}
catch(std::exception& e)
{
std::cerr << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit" << std::endl;
return ERROR_UNHANDLED_EXCEPTION;
}
return SUCCESS;
} // main
Basic option configuration
desc.add_options()
call in the application template.
Add the most simple of options
--option
("option", "Info message about option")
Add a shorthand for an option
--option or -o
("option,o", "Info message about option") // can use -o
Add an option with shorthand only
-o
(",o", "Info message about option") // must use -o
NOTE: To access a shorthand only value in a variables_map format the name as you would on the command line e.g. -o. See the Accessing Option Values section for more details.
Add an option that has an associated value
--option <value>
("option", po::value<arg_type>(), "Info message about option")
Specify that an option is required
po::notify(vm)
will throw if the option is not specified.
("option", po::value<arg_type>()->required(), "Info message")
Specify an option that can be specified multiple times
--option <value1> --option <value2> --option <value3>
("option", po::value<std::vector<arg_type> >(), "a list of values")
Accessing option values
Have the option set directly into an existing variable
I find this to be the most convenient method to use
("option", po::value<arg_type>(&existingVariable), "info message")
Check if an option was passed in the command line
if ( vm.count("option") )
To extract the value for an option manually
vm["option"].as<arg_type>()
Retrieving shorthand only options
Access to shorthand options is done exactly the same way as described above but the "option" string has to be formatted in a particular way. If there is only a shorthand option then the name for that option is considered to be "-X" where X is the letter being used as the short hand. Another way to remember this is to specify the name as it would appear on the command line.
(",t", "Shorthand only option -t")
if ( vm.count("-t") )
{
vm["-t"].as<arg_type>()
}
Specifying Positional Options
A positional option is a value given on the command line that is not preceded by an option switch like -o or --option. An example is the following:
In this case main.cpp is the positional option, and as you can see it is not associated with any option explicitly specified. Instead of being identified by an option switch (like --option) they are identified by the lack of one. When multiple positional options are available the option the value is assigned to is designated by the order in which the values appear in the command line.
In this case 'help' is the first positional option and 'commit' is the second. The command will print help info for the commit subcommand. Now if the order were to be reversed:
The position of the options is now reversed and the command will now try to 'commit' the location 'help'. Again the order in which values are specified determines which positional option the value is assigned to.
Example code for positional options
po::positional_options_description
object and specify the names of the options that you want to parse as positional. Add the following code block directly below the last option in the
desc.add_options()
call:
po::positional_options_description positionalOptions;
positionalOptions.add("option_name_1", <num_occurrences>);
positionalOptions.add("option_name_2", <num_occurrences>);
The option name specified as the first parameter must correspond to the name of an option already specified in the regular options description. The second parameter specifies the number of values to be associated with the option, in the simple case you will always set this to 1. The positional order of options is implied by the order in which they are added to the description, in this case 'option_name_1' is first and 'option_name_2' is second.
po::store()
call to the following:
po::store(po::command_line_parser(argc, argv).options(desc)
.positional(positionalOptions).run(),
vm);
Putting it all together
With just the information above you can create quite sophisticated command line applications, but sometimes knowing the parts does not give a good enough picture of what can be achieved. Check out below for a full example of the options implemented in a demo application. This should help to give you an idea of how things look when it’s all put together. Be aware that I have implemented some custom parsing for printing the available options in posix style which I include as part of the source package for the example application and an example of that usage output is shown immediately below. The information is parsed generically from the specified options and this prevents you from having to manually update help text when you update options (which is pretty awesome).
Best of luck, and please let me know if you have any issues.
Please note you will need version 1.50.0 of boost to compile the extended example
Usage Output
This is just a template app that should be modified and added to in order to create a useful command line application
USAGE: test_bed [-hvt] [-w ARG] [-m ARG] -n ARG add like
-- Option Descriptions --
Positional arguments:
add "additional options"
like "this"
Option Arguments:
-h [ --help ] Print help messages
-v [ --verbose ] print words with verbosity
-w [ --word ] words for the sentence, specify multiple times
-t just a temp option that does very little
-n [ --necessary ] give me anything
-m [ --manual ] extract value manually
Example Application
#include "PrettyOptionPrinter.hpp"
#include "boost/program_options.hpp"
#include "boost/filesystem.hpp"
#include <iostream>
#include <string>
namespace
{
const size_t ERROR_IN_COMMAND_LINE = 1;
const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // namespace
//------------------------------------------------------------------------
int main(int argc, char** argv)
{
try
{
std::string appName = boost::filesystem::basename(argv[0]);
int add = 0;
int like = 0;
std::vector<std::string> sentence;
/** Define and parse the program options
*/
namespace po = boost::program_options;
po::options_description desc("Options");
desc.add_options()
("help,h", "Print help messages")
("verbose,v", "print words with verbosity")
("word,w", po::value<std::vector<std::string> >(&sentence),
"words for the sentence, specify multiple times")
(",t", "just a temp option that does very little")
("necessary,n", po::value<std::string>()->required(), "necessary!")
("manual,m", po::value<std::string>(), "extract value manually")
("add", po::value<int>(&add)->required(), "additional options")
("like", po::value<int>(&like)->required(), "this");
po::positional_options_description positionalOptions;
positionalOptions.add("add", 1);
positionalOptions.add("like", 1);
po::variables_map vm;
try
{
po::store(po::command_line_parser(argc, argv).options(desc)
.positional(positionalOptions).run(),
vm); // throws on error
/** --help option
*/
if ( vm.count("help") )
{
std::cout << "This is just a template app that should be modified"
<< " and added to in order to create a useful command"
<< " line application" << std::endl << std::endl;
rad::OptionPrinter::printStandardAppDesc(appName,
std::cout,
desc,
&positionalOptions);
return SUCCESS;
}
po::notify(vm); // throws on error, so do after help in case
// there are any problems
}
catch(boost::program_options::required_option& e)
{
rad::OptionPrinter::formatRequiredOptionError(e);
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
rad::OptionPrinter::printStandardAppDesc(appName,
std::cout,
desc,
&positionalOptions);
return ERROR_IN_COMMAND_LINE;
}
catch(boost::program_options::error& e)
{
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
rad::OptionPrinter::printStandardAppDesc(appName,
std::cout,
desc,
&positionalOptions);
return ERROR_IN_COMMAND_LINE;
}
// can do this without fear because it is required to be present
std::cout << "Necessary = "
<< vm["necessary"].as<std::string>() << std::endl;
if ( vm.count("verbose") )
{
std::cout << "VERBOSE PRINTING" << std::endl;
}
if (vm.count("verbose") && vm.count("t"))
{
std::cout << "heeeeyahhhhh" << std::endl;
}
std::cout << "Required Positional, add: " << add
<< " like: " << like << std::endl;
if ( sentence.size() > 0 )
{
std::cout << "The specified words: ";
std::string separator = " ";
if (vm.count("verbose"))
{
separator = "__**__";
}
for(size_t i=0; i<sentence.size(); ++i)
{
std::cout << sentence[i] << separator;
}
std::cout << std::endl;
}
if ( vm.count("manual") )
{
std::cout << "Manually extracted value: "
<< vm["manual"].as<std::string>() << std::endl;
}
}
catch(std::exception& e)
{
std::cerr << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit" << std::endl;
return ERROR_UNHANDLED_EXCEPTION;
}
return SUCCESS;
} // main
//------------------------------------------------------------------------
how to use boost program options的更多相关文章
- Boost 库Program Options--第二篇
程式執行參數處理函式庫:Boost Program Options(2/N) 前一篇已經大致解釋了 Boost Program Options 基本上的使用方法.而這一篇,則來細講一下選項描述(opt ...
- boost:库program_options--第一篇
程式執行參數處理函式庫:Boost Program Options(1/N) 一般程式寫得大一點.或是需要比較有彈性,通常都需要在程式執行的時候,從外部讀取一些參數,來做為內部的設定值.一般來說,比較 ...
- Boost简介
原文链接: 吴豆豆http://www.cnblogs.com/gdutbean/archive/2012/03/30/2425201.html Boost库 Boost库是为C++语言标准库提供扩 ...
- Boost 1.61.0 Library Documentation
http://www.boost.org/doc/libs/1_61_0/ Boost 1.61.0 Library Documentation Accumulators Framework for ...
- boost库的安装,使用,介绍,库分类
1)首先去官网下载boost源码安装包:http://www.boost.org/ 选择下载对应的boost源码包.本次下载使用的是 boost_1_60_0.tar.gz (2)解压文件:tar - ...
- [C++Boost]程序参数项解析库Program_options使用指南
介绍 程序参数项(program options)是一系列name=value对,program_options 允许程序开发者获得通过命令行(command line)和配置文件(config fi ...
- boost库中的 program_options
1.阅读rviz中的源码时在rviz/visualizer_app.cpp中遇到如下代码: po::options_description options; options.add_options() ...
- C++ Boost库分类总结
c# 程序员写c++,各种不适应.尤其是被内存操作和几十种字符串类型的转换,简直疯了,大小写转换竟然要手动写代码实现. Boost看介绍不错,也不知道能不能跨平台.过几天要上linux写c++, 也不 ...
- boost 介绍
简介: Boost库是一个可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一. Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容 ...
随机推荐
- HDU 5988 Coding Contest(费用流+浮点数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 题目大意: 给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭.每个点有S个人,有B盒 ...
- Codeforces 519D A and B and Interesting Substrings(二维map+前缀和)
题目链接:http://codeforces.com/problemset/problem/519/D 题目大意:给你一串字符串s仅由小写字母组成,并且对于'a'~'z'都给了一个值.求子串t满足t的 ...
- python接口自动化测试六:时间戳,防重复处理
对于不可重复参数,可以用时间戳,防重复 import time title = '这是我的标题:%s'%str(int(time.time())) print(title) 转化成时间格式 t = t ...
- 使用fidder进行接口测试
官方下载地址 下载后一路next安装即可. get请求 get请求直接把需要携带的参数使用?跟在后面如:http://127.0.0.1:8000/api/get_event_list/?id=1 p ...
- 更好用的cmd窗口
cmder是windows下的命令行工具,用来替代windows自带的cmd. 下载地址 下载后自建文件夹并解压,将Cmder.exe所在文件夹路径加入path, windows + r 键入cmde ...
- 2017-2018-2 20155309 南皓芯 Exp7 网络欺诈防范
实践内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 1,简单应用SET工具建立冒名网站 2.ettercap DNS spoof 3.结合应用两种技术,用 ...
- Ext.js入门(二)
ExtJs OOP基础 一:ExtJs中的面向对象 1.ExtJs中命名空间的定义 Ext中的命名空间类似于C#中的namespace和java中的包,用来对工程中的类进行更好的 ...
- python访问百度地图接口并返回信息
import urllib.parse import urllib.request data = urllib.parse.urlencode({'address': '广东省湛江市霞山区', 'ou ...
- Spring之对象依赖关系(依赖注入Dependency Injection)
承接上篇: Spring中,如何给对象的属性赋值: 1:通过构造函数,如下所示: <!-- 1:构造函数赋初始值 --><bean id="user1" clas ...
- springbank 开发日志 Spring启动过程中对自定义标签的处理
这篇随笔的许多知识来源于:http://www.importnew.com/19391.html 之所以会去看这些东东,主要是希望能够模仿spring mvc的处理流程,做出一套合理的交易处理流程. ...