微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将空字符串引用例如“”作为值传递给未注册的 boost::program_options

如何解决将空字符串引用例如“”作为值传递给未注册的 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?