如何确定是否向 boost::program_options 提供了一个参数,或者是否使用了默认值?
How to determine if an argment was provided to boost::program_options, or if the default is used instead?
使用 boost::program_options
,我需要设置 default_value
以便在帮助消息中显示默认值。但是,仍然需要知道是否应用了默认值或是否提供了参数。 (在某些情况下,如果提供了参数,逻辑将覆盖现有配置)。
可能的解决方案:
删除默认值:但帮助消息将不会显示默认值。
找到一种方法来检查是否提供了参数(如何?)
创建 option_description
两次(一次有默认值,另一次没有)。不理想。
int main( int argc, char* argv[])
{
namespace po = boost::program_options;
namespace fs = boost::filesystem;
std::string ip;
std::string port;
const std::string ip_arg = "ip";
const std::string port_arg = "ip";
po::options_description options("Options");
options.add_options()
(ip_arg, po::value<std::string>(&ip, "IP")->default_value("127.0.0.1")
(port_arg, po::value<std::string>(&port, "Port")->default_value("80"))
;
po::variables_map vm;
try
{
using bs = po::command_line_style::style_t;
boost::program_options::store(
boost::program_options::command_line_parser(argc, argv)
.options(options)
.style(bs::long_allow_next | bs::allow_long | bs::allow_short | bs::allow_dash_for_short |
bs::long_allow_adjacent | bs::short_allow_adjacent | bs::short_allow_next | bs::allow_long_disguise)
.run(),
vm);
po::notify(vm);
}
catch( ...)
{
std::cerr << "Some error" << std::endl;
return 1;
}
std::stringstream ss;
ss << options;
std::cout << ss.str() << std::endl; // Print help, visible defaults
if (vm.count(port_arg))
{
// Argument was provided, so make something
}
else
{
// Argument was no provided, make something else.
}
return 0;
}
如何检测是否提供了参数,或者是否应用了默认值?
您的选项描述已损坏。让我们修复它们。我选择反对 ip_arg
/port_arg
变量(注意你是如何让它们复制粘贴错误的)。
po::options_description options("Options");
options.add_options()
("ip", po::value<std::string>(&ip)->default_value("127.0.0.1"), "IP") //
("port", po::value<std::string>(&port)->default_value("80"), "Port")
;
现在您可以确定 port
始终已设置,因此 .count()
或 .contains()
是多余的。相反,询问地图条目是否已被默认:
if (vm["port"].defaulted()) {
std::cout << "Port defaulted (" << port << ")\n";
} else {
std::cout << "Port specified as " << port << "\n";
}
现场演示
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
namespace fs = boost::filesystem;
int main( int argc, char* argv[])
{
std::string ip;
std::string port;
po::options_description options("Options");
options.add_options()
("ip", po::value<std::string>(&ip)->default_value("127.0.0.1"), "IP") //
("port", po::value<std::string>(&port)->default_value("80"), "Port")
;
po::variables_map vm;
try {
using bs = po::command_line_style::style_t;
boost::program_options::store(
boost::program_options::command_line_parser(argc, argv)
.options(options)
.style(bs::long_allow_next | bs::allow_long | bs::allow_short |
bs::allow_dash_for_short | bs::long_allow_adjacent |
bs::short_allow_adjacent | bs::short_allow_next |
bs::allow_long_disguise)
.run(),
vm);
po::notify(vm);
} catch (...) {
std::cerr << "Some error" << std::endl;
return 1;
}
std::cout << options << std::endl;
if (vm["port"].defaulted()) {
std::cout << "Port defaulted (" << port << ")\n";
} else {
std::cout << "Port specified as " << port << "\n";
}
}
打印例如
$ ./test --ip=192.168.1.2
Options:
--ip arg (=127.0.0.1) IP
--port arg (=80) Port
Port defaulted (80)
或
$ ./test --port=8080
Options:
--ip arg (=127.0.0.1) IP
--port arg (=80) Port
Port specified as 8080
使用 boost::program_options
,我需要设置 default_value
以便在帮助消息中显示默认值。但是,仍然需要知道是否应用了默认值或是否提供了参数。 (在某些情况下,如果提供了参数,逻辑将覆盖现有配置)。
可能的解决方案:
删除默认值:但帮助消息将不会显示默认值。
找到一种方法来检查是否提供了参数(如何?)
创建
option_description
两次(一次有默认值,另一次没有)。不理想。int main( int argc, char* argv[]) { namespace po = boost::program_options; namespace fs = boost::filesystem; std::string ip; std::string port; const std::string ip_arg = "ip"; const std::string port_arg = "ip"; po::options_description options("Options"); options.add_options() (ip_arg, po::value<std::string>(&ip, "IP")->default_value("127.0.0.1") (port_arg, po::value<std::string>(&port, "Port")->default_value("80")) ; po::variables_map vm; try { using bs = po::command_line_style::style_t; boost::program_options::store( boost::program_options::command_line_parser(argc, argv) .options(options) .style(bs::long_allow_next | bs::allow_long | bs::allow_short | bs::allow_dash_for_short | bs::long_allow_adjacent | bs::short_allow_adjacent | bs::short_allow_next | bs::allow_long_disguise) .run(), vm); po::notify(vm); } catch( ...) { std::cerr << "Some error" << std::endl; return 1; } std::stringstream ss; ss << options; std::cout << ss.str() << std::endl; // Print help, visible defaults if (vm.count(port_arg)) { // Argument was provided, so make something } else { // Argument was no provided, make something else. } return 0; }
如何检测是否提供了参数,或者是否应用了默认值?
您的选项描述已损坏。让我们修复它们。我选择反对 ip_arg
/port_arg
变量(注意你是如何让它们复制粘贴错误的)。
po::options_description options("Options");
options.add_options()
("ip", po::value<std::string>(&ip)->default_value("127.0.0.1"), "IP") //
("port", po::value<std::string>(&port)->default_value("80"), "Port")
;
现在您可以确定 port
始终已设置,因此 .count()
或 .contains()
是多余的。相反,询问地图条目是否已被默认:
if (vm["port"].defaulted()) {
std::cout << "Port defaulted (" << port << ")\n";
} else {
std::cout << "Port specified as " << port << "\n";
}
现场演示
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
namespace fs = boost::filesystem;
int main( int argc, char* argv[])
{
std::string ip;
std::string port;
po::options_description options("Options");
options.add_options()
("ip", po::value<std::string>(&ip)->default_value("127.0.0.1"), "IP") //
("port", po::value<std::string>(&port)->default_value("80"), "Port")
;
po::variables_map vm;
try {
using bs = po::command_line_style::style_t;
boost::program_options::store(
boost::program_options::command_line_parser(argc, argv)
.options(options)
.style(bs::long_allow_next | bs::allow_long | bs::allow_short |
bs::allow_dash_for_short | bs::long_allow_adjacent |
bs::short_allow_adjacent | bs::short_allow_next |
bs::allow_long_disguise)
.run(),
vm);
po::notify(vm);
} catch (...) {
std::cerr << "Some error" << std::endl;
return 1;
}
std::cout << options << std::endl;
if (vm["port"].defaulted()) {
std::cout << "Port defaulted (" << port << ")\n";
} else {
std::cout << "Port specified as " << port << "\n";
}
}
打印例如
$ ./test --ip=192.168.1.2
Options:
--ip arg (=127.0.0.1) IP
--port arg (=80) Port
Port defaulted (80)
或
$ ./test --port=8080
Options:
--ip arg (=127.0.0.1) IP
--port arg (=80) Port
Port specified as 8080