c++ - 将空字符串引号(例如“”)作为值传递给未注册的 boost::program_options
问题描述
概括
我见过这个问题,它询问并回答了如何为定义的值传递无操作。但是,如何从命令行将空字符串传递给对象,尤其是对于未注册的选项?以及如何避免由于传入空字符串/值而导致提升分段错误?
细节
例如,我有如下所示的选项。它们被程序的主入口点视为未注册。然后将它们传递给另一个库进行解析。
# These are equivalent, with and without quotes
--MyLibrary.myCsv="one,two,three"
--MyLibrary.myCsv=one,two,three
但是,此选项可以为空,例如:
--MyLibrary.myCsv=""
现在,由于 shell 删除了引号,这会引发 SegFault(至少对于 boost 1.67 之前的版本)。明确地说,我得到一个异常,然后是 SegFault 消息“中止(核心转储)”:
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
解决方案
推荐阅读
- mysql - 子查询选择内部 where 子句的外部值
- c# - 阻止 BroadcastBlock 在 LinkTo 上发送缓冲消息
- python - Python:即使检测到设备,也无法使用 PyBluez 扫描连接到蓝牙设备所需的信息
- c# - 找不到类型或命名空间名称“DefaultHttpRequest”
- vue.js - Vuex:如何用 Vuex 替换父子之间的函数发射?
- python - 矩阵创建和赋值 Python
- flutter - 颤动动态文本方向性问题
- jquery - 我想在 cartDetails() 中使用“this”,但显示 Uncaught TypeError
- selenium - Selenium xUnit 无法与 IE 一致地工作
- python - 使用字典过滤 dask 数据帧