使用Boost Program Options,你如何获得argv [0]的字符串等价物?
美好的一天,
我写了一个类来通过boost :: program_options解析配置文件.这是我的(缩短):
namespace nsProOp = boost::program_options;
nsProOp::variables_map m_variableMap;
nsProOp::options_description m_description;
// To add options to the variableMap, e.g. "addOption<int>("money_amount");"
template <class T>
void addOption(const std::string& option, const std::string& helpDescription = "") {
m_description.add_options()(option.c_str(), nsProOp::value<T > (), helpDescription.c_str());
}
// And this is how i actually read the file:
void ConfigFile::parse() {
std::ifstream file;
file.open(m_pathToFile.c_str());
nsProOp::store(nsProOp::parse_config_file(file, m_description, true), m_variableMap);
nsProOp::notify(m_variableMap);
}
Run Code Online (Sandbox Code Playgroud)
好的,这很好用.但我希望能够再次解析同一个文件,以便我总是使用用户提供的最新条目!关于"商店"的提升文档说:
"在'm'中存储''选项'中定义的所有选项.如果'm'已经具有选项的非默认值,则该值不会更改,即使'options'指定了某个值."
所以,如果我再次调用"parse()"则没有任何反应,因为m_variableMap已被填充.我尝试调用m_variableMap.clear()并不能解决我的问题,因此存储只能在第一次工作.
有人给我一个建议吗?如果我的问题不清楚,请告诉我.谢谢!
我正在使用Boost Program Options来解析命令行参数(我不想错过它,因为它工作得很好).但是,我有一个问题:Boost程序选项提供了为每个选项分配描述的可能性.然后Boost提供了可能性
cout << program_options_description << endl
很好地显示帮助解释选项.然而,似乎是这些错误消息被调整到终端宽度为80的情况(我从这样的事实得出结论:对于80的宽度,线断开很好地设置).
如果我当前的终端有另一个宽度(特别是一个少于80列的宽度),由于终端自动换行,显示的帮助看起来非常不自然.
那么:Boost是否有可能自动将选项描述调整为当前终端宽度?
假设我有一个程序使用boost :: program_options来解析命令行参数,并且有一个unsigned值:
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
int main(int argc, char* argv[]) {
unsigned num;
po::options_description desc;
desc.add_options()
("num,n", po::value<unsigned>(&num), "Non-negative number");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
std::cout << "Number: " << num << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后,如果我在命令行上传递一个负值,它会接受它并将其包装起来:
$ ./bponeg -n -1 Number: 4294967295
我宁愿负数会触发错误(即抛出invalid_option_value),就像我写的那样./bponeg -n abc.在解析之后,从我自己的代码中,似乎无法区分用户编写的情况-1或他们写的情况4294967295.
我可以指示program_options解析器拒绝unsigned值的负输入吗?
感谢所有提供帮助的人!最终起作用的是改变:
set(CMAKE_CXX_COMPILER "gcc-10")
set(CMAKE_C_COMPILER "g++-10")
Run Code Online (Sandbox Code Playgroud)
到:
set(CMAKE_CXX_COMPILER "/usr/local/opt/llvm/bin/clang")
set(CMAKE_C_COMPILER "/usr/local/opt/llvm/bin/clang++")
Run Code Online (Sandbox Code Playgroud)
尝试将 boost 链接到我的程序时出现以下错误:
[ 83%] Linking CXX executable cartogram
Undefined symbols for architecture x86_64:
"__ZN5boost15program_options11to_internalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
__ZN5boost15program_options11to_internalINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESt6vectorIS7_SaIS7_EERKS8_IT_SaISB_EE in main.cpp.o
"__ZN5boost15program_options16validation_error12get_templateB5cxx11ENS1_6kind_tE", referenced from:
__ZN5boost15program_options10validators17get_single_stringIcEERKNSt7__cxx1112basic_stringIT_St11char_traitsIS5_ESaIS5_EEERKSt6vectorIS9_SaIS9_EEb in main.cpp.o
"__ZN5boost15program_options19options_descriptionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj", referenced from:
_main in main.cpp.o
"__ZN5boost15program_options20invalid_option_valueC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
__ZN5boost15program_options8validateIicEEvRNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIT0_St11char_traitsIS7_ESaIS7_EEESaISB_EEPT_l in main.cpp.o
"__ZN5boost15program_options22error_with_option_nameC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_i", referenced from:
__ZN5boost15program_options10validators17get_single_stringIcEERKNSt7__cxx1112basic_stringIT_St11char_traitsIS5_ESaIS5_EEERKSt6vectorIS9_SaIS9_EEb in main.cpp.o
"__ZN5boost15program_options3argB5cxx11E", referenced from:
__ZNK5boost15program_options11typed_valueIbcE4nameB5cxx11Ev in main.cpp.o
__ZNK5boost15program_options11typed_valueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcE4nameEv in main.cpp.o
__ZNK5boost15program_options11typed_valueIicE4nameB5cxx11Ev in main.cpp.o
"__ZN5boost15program_options6detail7cmdline21set_additional_parserENS_9function1ISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ERKSA_EE", referenced from:
__ZN5boost15program_options25basic_command_line_parserIcE12extra_parserENS_9function1ISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ERKSA_EE in main.cpp.o
"__ZN5boost15program_options6detail7cmdlineC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE", referenced from:
__ZN5boost15program_options25basic_command_line_parserIcEC1EiPKPKc in main.cpp.o
"__ZN5boost15program_options8validateERNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEPS9_i", referenced …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用C++和boost开发一个跨平台的应用程序.
我通常在*nix环境中编程,我总是在其中定义'main',如下所示:
int main( const int argc, const char* argv[] )
{
...
}
Run Code Online (Sandbox Code Playgroud)
对于这个应用程序,我使用Visual Studio 2003在Windows环境中启动.
当我尝试使用带有此定义的boost :: program_options时,我从program_options :: store获得编译错误:
po::options_description desc("Supported options");
desc.add_options()...;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
Run Code Online (Sandbox Code Playgroud)
错误:
main.cpp(46) : error C2665: 'boost::program_options::store' : none of the 2 overloads can convert parameter 1 from type 'boost::program_options::basic_parsed_options<charT>'
with
[
charT=const char
]
c:\boost_1_38_0\boost\program_options\variables_map.hpp(34): could be 'void boost::program_options::store(const boost::program_options::basic_parsed_options<charT> &,boost::program_options::variables_map &,bool)'
with
[
charT=char
]
c:\boost_1_38_0\boost\program_options\variables_map.hpp(43): or 'void boost::program_options::store(const boost::program_options::basic_parsed_options<wchar_t> &,boost::program_options::variables_map &)'
while trying to match the …Run Code Online (Sandbox Code Playgroud) 使用boost :: program_options,在命名空间内声明时,我无法获得自己的选项类型进行编译.但是在命名空间之外它编译并且工作正常:
#include <boost/program_options.hpp>
using namespace boost;
using namespace boost::program_options;
struct my_type1 {
my_type1(int nn) : n(nn) {}
int n;
};
namespace nm {
struct my_type2 {
my_type2(int nn) : n(nn) {}
int n;
};
}
void validate(boost::any& v,
const std::vector<std::string>& values,
my_type1*, int) {
const std::string& s = validators::get_single_string(values);
v = any(my_type1(lexical_cast<int>(s)));
}
void validate(boost::any& v,
const std::vector<std::string>& values,
nm::my_type2*, int) {
const std::string& s = validators::get_single_string(values);
v = any(nm::my_type2(lexical_cast<int>(s)));
}
int main() {
options_description desc("options");
desc.add_options()
("m1", …Run Code Online (Sandbox Code Playgroud) 这些天我正在使用Boost程序选项来读取INI文件.
我在代码中抛出一个异常,有一行带有未知选项.你知道是否可能以及如何让下面的代码读取整个文件?我想跳过未知选项而不抛出,以便我可以读取所有可能的值.非常感谢AFG
namespace pod = boost::program_options;
pod::options_description options("Options");
std::string myArgValue;
options.add_options()
("SECT_A.Option_A",
pod::value<int>()->default_value(1),
"xxx")
("SECT_B.Option_B",
pod::value<std::string>(&myArgValue),
"xxx")
;
pod::variables_map vm;
pod::store( pod::parse_config_file( s, options ) , vm);
pod::notify( vm );
Run Code Online (Sandbox Code Playgroud) 我试图使用Boost ProgramOptions来解析配置文件以初始化我自己的类类型Dataset(下面的代码)
我将选项添加为:
config_.add_options()("dataset", po::value<Dataset>()->required(),"Dataset");
Run Code Online (Sandbox Code Playgroud)
我的数据集类定义如下:
#ifndef DATASET_H_
#define DATASET_H_
#include <boost/algorithm/string/predicate.hpp>
class Dataset {
public:
enum Name {
JAVA, SUMATRA, ASIA, AFRICA
};
Dataset(Name name = JAVA) : name_(name) {}
operator Name () const {return name_;}
std::string asString() const;
private:
Name name_;
//prevent automatic conversion for any other built-in types such as bool, int, etc
template<typename T>
operator T() const;
};
inline std::string Dataset::asString() const {
if (name_ == Dataset::JAVA)
return "JAVA";
else if (name_ == Dataset::SUMATRA)
return "SUMATRA"; …Run Code Online (Sandbox Code Playgroud) 我有一个配置文件格式,我希望用Boost程序选项实现(因为我之前使用过该库),但我不得不实现这样的块:
label = whatever
depth = 3
start
source = /etc
dest = /tmp/etc/
end
start
source = /usr/local/include
dest = /tmp/include
depth = 1
end
Run Code Online (Sandbox Code Playgroud)
我在文档中读到了我可以拥有的内容[sections],所以我首先想知道这个:
label = whatever
depth = 3
[dir]
source = /etc
dest = /tmp/etc/
[dir]
source = /usr/local/include
dest = /tmp/include
depth = 1
Run Code Online (Sandbox Code Playgroud)
但是,如果我理解正确,dir它将成为变量名称的一部分,因此不可能重复,这是行不通的.那么我想知道要source转变为部分名称:
label = whatever
depth = 3
[/etc]
dest = /tmp/etc/
[/usr/local/include]
dest = /tmp/include
depth = 1
Run Code Online (Sandbox Code Playgroud)
这似乎是一种合理的方法吗?当我不提前知道部分名称时,我想知道如何迭代部分列表?
或者,有没有更好的方法来使用程序选项库来实现这一目标?