如何解决将空字符串引用例如“”作为值传递给未注册的 boost::program_options
总结
我见过 this 问题,该问题询问并回答了如何为定义的值传递无操作。但是,如何从命令行将空字符串传递给对象,尤其是对于未注册的选项?以及如何避免由于传入空字符串/值而导致提升分段错误?
详情
例如,我有如下所示的选项。它们被程序的主要入口点视为未注册。然后将它们传递给另一个库进行解析。
# These are equivalent,with and without quotes
--MyLibrary.myCsv="one,two,three"
--MyLibrary.myCsv=one,three
但是,此选项可以为空,例如:
--MyLibrary.myCsv=""
现在,由于 shell 删除了引号,这会引发 SegFault(至少对于 boost 1.67 之前的版本)。明确地说,我收到一个异常,然后是 SegFault 消息“Aborted (core dumped)”:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::invalid_command_line_Syntax> >'
what(): the argument for option '--MyLibrary.myCsv' should follow immediately after the equal sign
(core dumped)
我可以这样写:
--MyLibrary.myCsv=\"\"
它不会出现段错误,但幽默的是,它会将值设置为 "\"\""
,这显然不是一个空字符串......有没有办法只给出它是一个空字符串值?
示例代码
这是一个小例子(希望如此)展示了我的问题。我叫它emptyQuotes.cpp
#include <iostream>
#include <vector>
#include <string>
#include <boost/program_options.hpp>
using namespace std;
namespace po = boost::program_options;
/**
* @brief parser for another (potentially external) library.
*
* For simplicity,it looks for '=' to split key from value
*/
void libraryParser( const vector<string>& options )
{
for ( auto it = options.begin(); it != options.end(); ++it )
{
size_t eqPos = it->find('=');
size_t start = it->find_first_not_of('-');
string key = it->substr(start,eqPos-start);
string val = it->substr(eqPos + 1);
cout << " key = \"" << key << "\"; val = \"" << val << "\"\n";
cout << " Is val empty? ";
if(val.empty())
cout << "yes";
else
cout << "no";
cout << "\n";
}
}
int main (int argc,char** argv)
{
cout << "Command line:\n ";
for ( int ii = 0; ii < argc; ++ii )
cout << argv[ii] << " ";
cout << "\n";
// Commands that the basic entry point would kNow
boost::program_options::options_description basic("Basic");
basic.add_options()
( "help,h","produce a help message" );
po::parsed_options parsed = po::command_line_parser(argc,argv)
.options(basic)
.allow_unregistered() // <-I don't kNow how to handle blank values here
.run();
po::variables_map vm;
po::store(parsed,vm);
vector<string> unregOptions = po::collect_unrecognized( parsed.options,po::exclude_positional );
libraryParser(unregOptions);
cout << "\n";
return 0;
}
运行以下得到SegFault:
./emptyQuotes --MyLibrary.myVal=""
Command line:
./emptyQuotes --MyLibrary.myVal=
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::invalid_command_line_Syntax> >'
what(): the argument for option '--MyLibrary.myVal' should follow immediately after the equal sign
Aborted (core dumped)
并且它报告该值不是带斜杠的空值:
./emptyQuotes --MyLibrary.myVal=\"\"
Command line:
./emptyQuotes --MyLibrary.myVal=""
key = "MyLibrary.myVal"; val = """"
Is val empty? no
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。