c++ - 如何让 boost::program_options 与 boost::posix_time::ptime 一起工作?

标签 c++ boost boost-program-options boost-date-time

我已经多次尝试让它工作但没有成功。该程序可以编译,但我能想到的提供给该程序的每个时间戳格式都是无效的。

#include <boost/program_options.hpp>
#include <boost/optional.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <string>
using namespace boost::program_options;
using namespace std;

int main(int argc, const char** argv) {
    boost::posix_time::ptime forceDate;
    boost::optional<boost::posix_time::ptime> forceDateOptional;

    options_description descr("Options");
    descr.add_options()
    ("force-date,a", value(&forceDate)->value_name("<date>"), "...");

    try {
        variables_map args;
        store(command_line_parser(argc, argv).options(descr).run(), args);
        notify(args);
        cout << "Done." << endl;
        return 0;
    } catch (std::exception& e) {
        cerr << e.what() << endl;
        return 1;
    }
}

使用g++ -I/usr/local/include -L/usr/local/lib -lboost_program_options -lboost_system x.cpp编译并使用./a.out --force运行-日期2012-01-03

这是抛出异常的错误:

the argument ('2012-01-03') for option '--force-date' is invalid

最佳答案

让我们首先尝试通过删除 program_options 并尝试从流中解析 posix_time::ptime 来简化示例。

boost::posix_time::ptime forceDate;
std::istringstream ss("2012-01-03");
if(ss >> forceDate) {
    std::cout << forceDate << "\n";
}

上面的示例没有打印任何内容,因此显然解析出了问题。如果您查找documentation对于 operator>> ,很明显,月份的预期格式是缩写名称而不是数值。

如果将上面的代码改为

boost::posix_time::ptime forceDate;
std::istringstream ss("2012-Jan-03");
if(ss >> forceDate) {
    std::cout << forceDate << "\n";
}

它产生所需的输出。

进一步挖掘documentation显示控制输入格式的方法是使用 boost::posix_time::time_input_facetset_iso_extended_format 将格式设置为您要使用的数字格式。

boost::posix_time::ptime forceDate;
std::istringstream ss("2012-01-03");

auto facet = new boost::posix_time::time_input_facet();
facet->set_iso_extended_format();

ss.imbue(std::locale(ss.getloc(), facet));
if(ss >> forceDate) {
    std::cout << forceDate << "\n";
}

Live demo


现在返回program_options。看起来该库没有直接提供区域设置支持,因此我可以让上述解决方案发挥作用的唯一方法是扰乱全局区域设置。如果您将以下几行添加到示例中,它的行为就会如您所愿。

auto facet = new boost::posix_time::time_input_facet();
facet->set_iso_extended_format();
std::locale::global(std::locale(std::locale(), facet));

Live demo

关于c++ - 如何让 boost::program_options 与 boost::posix_time::ptime 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33427997/

相关文章:

c++ - 我的对象在 vector 中的地址发生变化

c++ - 比较模板类型和具体类型的实例

c++ - 默认语言环境 "root"在 ICU 中如何工作?

c++ - boost 和图形化

c++ - 两个矩阵的C++高效按元素匹配

c++ - Boost图在子图中找到边

c++ - boost::future::那么它是如何实现的呢?

c++ - 如何为 boost::program_options 的位置选项添加描述?

c++ - 如何在不使用变量的情况下启用 Boost Program Options 中的其他选项?

c++ - 自定义验证器不允许 default_value