I have some trouble reading from an ini file using boost program options. The problem is a key which contains hashmarks (simplyfied example):
[section]
key="xxx#yyy"Retrieving the key, returns "xxx", which is because the hashmark seems to be interpreted as start of a comment and therefore the rest of the line is skipped. Unfortunately I cannot substitute the '#' by some other character because the value is a regular expression. I didn't find a way to quote the hashmark and would prefer not to do it, because it would开发者_StackOverflow中文版 alter my regex and make it even more unreadable.
Is there a way to deal with this problem without rewriting the ini-file parser? Thanks for any help.
My code to retrieve the key looks like:
std::string key;
boost::program_options::options_description opDesc("test");
opDesc.add_options()("section.key", po::value<string>(&key))
std::ifstream ifs("file.ini");
boost::program_options::parse_config_file(ifs, opDesc);
Perhaps it is time to start using Boost Property Tree as you are way past the 'I'm parsing program options' point here, really.
http://www.boost.org/doc/libs/1_46_1/doc/html/property_tree.html
Property tree has parsers/formatters for JSON, Xml, Ini (<-- you are here
) and the INFO formats. The linked page specifies in a few lines exactly what round-trips (most things roundtrip, except for JSON sepcific type information and sometimes trailing whitespace).
I suppose you'd like the INI format (because it's close to what you're using) and the INFO setting (because it has more string syntax, in addition to hierarchically nested sections).
From the samples:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>
struct debug_settings
{
std::string m_file; // log filename
int m_level; // debug level
std::set<std::string> m_modules; // modules where logging is enabled
void load(const std::string &filename);
void save(const std::string &filename);
};
void debug_settings::load(const std::string &filename)
{
using boost::property_tree::ptree;
ptree pt;
read_xml(filename, pt);
m_file = pt.get<std::string>("debug.filename");
m_level = pt.get("debug.level", 0);
BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))
m_modules.insert(v.second.data());
}
void debug_settings::save(const std::string &filename)
{
using boost::property_tree::ptree;
ptree pt;
pt.put("debug.filename", m_file);
pt.put("debug.level", m_level);
BOOST_FOREACH(const std::string &name, m_modules)
pt.add("debug.modules.module", name);
write_xml(filename, pt);
}
int main()
{
try
{
debug_settings ds;
ds.load("debug_settings.xml");
ds.save("debug_settings_out.xml");
std::cout << "Success\n";
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what() << "\n";
}
return 0;
}
精彩评论