Я использую Boost program_options для синтаксического анализа файла конфигурации как
, который показан в файле примеров multiple_sources.cpp program_options.Boost parse_config_file, пустое значение ключа
ifstream ini_file("config.ini");
po::store(po::parse_config_file(ini_file, desc, true), vm);
po::notify(vm);
файл config.ini однако имеет пустой ключ = значение пары, такие как:
key1=value1
key2=value2
key3=
key4=
key5=value5
Попытка прочитать этот файл приводит к ошибке Форсирование:
boost::program_options::invalid_option_value
Есть ли механизм в boost :: program_options для чтения таких файлов конфигурации с пустым?
Любая помощь будет высоко оценена.
Я редактирую этот вопрос, так как проблема еще не решена. Я просто приведу пример из Boost (1.53).
Это полный multiple_sources.cpp файл:
#include <boost/program_options.hpp>
namespace po = boost::program_options;
#include <iostream>
#include <fstream>
#include <iterator>
using namespace std;
// A helper function to simplify the main part.
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
return os;
}
int main(int ac, char* av[])
{
try {
int opt;
string config_file;
// Declare a group of options that will be
// allowed only on command line
po::options_description generic("Generic options");
generic.add_options()
("version,v", "print version string")
("help", "produce help message")
//("optimization","optimization level")
("config,c", po::value<string>(&config_file)->default_value("multiple_sources.cfg"),
"name of a file of a configuration.")
;
// Declare a group of options that will be
// allowed both on command line and in
// config file
po::options_description config("Configuration");
config.add_options()
("optimization", po::value<int>(&opt)->default_value(10),
"optimization level")
("include-path,I", po::value< vector<string> >()->composing(),
"include path")
;
// Hidden options, will be allowed both on command line and
// in config file, but will not be shown to the user.
po::options_description hidden("Hidden options");
hidden.add_options()
("input-file", po::value< vector<string> >(), "input file")
;
po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);
po::options_description config_file_options;
config_file_options.add(config).add(hidden);
po::options_description visible("Allowed options");
visible.add(generic).add(config);
po::positional_options_description p;
p.add("input-file", -1);
po::variables_map vm;
store(po::command_line_parser(ac, av).
options(cmdline_options).positional(p).run(), vm);
notify(vm);
ifstream ifs(config_file.c_str());
if (!ifs)
{
cout << "can not open config file: " << config_file << "\n";
return 0;
}
else
{
store(parse_config_file(ifs, config_file_options), vm);
notify(vm);
}
if (vm.count("help")) {
cout << visible << "\n";
return 0;
}
if (vm.count("version")) {
cout << "Multiple sources example, version 1.0\n";
return 0;
}
if (vm.count("include-path"))
{
cout << "Include paths are: "
<< vm["include-path"].as< vector<string> >() << "\n";
}
if (vm.count("input-file"))
{
cout << "Input files are: "
<< vm["input-file"].as< vector<string> >() << "\n";
}
cout << "Optimization level is " << opt << "\n";
}
catch(exception& e)
{
cout << e.what() << "\n";
return 1;
}
return 0;
}
И соответствующий файл конфигурации (multiple_sources.cfg) является:
#
# Comment out this line to use hard-coded default value of 10
#
optimization = 1
include-path = /opt
Если этот файл теперь изменен на:
#
# Comment out this line to use hard-coded default value of 10
#
optimization =
include-path = /opt
Выдается следующее сообщение об ошибке:
the argument for option 'optimization' is invalid
Предлагаемые решения с проверкой перегрузки и т. Д. Кажутся излишне сложными, тем более что для каждого типа данных может потребоваться написать функцию проверки, включающую возможность распознавания «\ n» другого белого пространства.
Любые предложения? Спасибо всем за то, что нашли время.
По предложению Адитья, я заменил следующую строку:
("optimization", po::value<int>(&opt)->default_value(10),
"optimization level")
со следующим:
("optimization", po::value<int>(&opt)->zero_tokens(),
"optimization level")
и:
("optimization", po::value<int>(&opt)->implicit_value(10),
"optimization level")
и ни один из них читал пустым опции. Повысьте пример программы «parser_test.cpp» обходит использование zero_tokens(), или implicit_value(), читая пары ключ-значение в вектор следующим образом:
void test_config_file(const char* config_file)
{
options_description desc;
desc.add_options()
("gv1", new untyped_value)
("gv2", new untyped_value)
("empty_value", new untyped_value)
("plug*", new untyped_value)
("m1.v1", new untyped_value)
("m1.v2", new untyped_value)
("b", bool_switch())
;
const char content1[] =
" gv1 = 0#asd\n"
"empty_value = \n"
"plug3 = 7\n"
"b = true\n"
"[m1]\n"
"v1 = 1\n"
"\n"
"v2 = 2\n"
;
vector<option> a2 = parse_config_file<char>(config_file, desc).options;
BOOST_REQUIRE(a2.size() == 6);
check_value(a2[0], "gv1", "0");
check_value(a2[1], "empty_value", "");
check_value(a2[2], "plug3", "7");
check_value(a2[3], "b", "true");
check_value(a2[4], "m1.v1", "1");
check_value(a2[5], "m1.v2", "2");
}
Посмотрите на: http://stackoverflow.com/questions/4459650/skipping-unknown-options-without-throwing-with-boost-program-options – ypnos
Спасибо за ссылку ypnos, однако у меня уже был взгляд в этом решении, и я добавил «true» в качестве третьего параметра в аргументах parse_config_file. Это все еще не решает проблему. Вы столкнулись с этой проблемой и решили ли это решение? –
Извините, тогда я вам не помогу. :/ Будет ли он работать, если у вас есть key3 = 1, key4 = 1 в файле конфигурации? – ypnos