2011-01-16 3 views
12

私は設定ファイルからパラメータを取得するためにboost :: program_optionsを使用しています。は、ブーストプログラムオプションの設定ファイルを出力する手段です。

私は手でファイルを作成することができ、プログラムオプションはそれを解析することを理解します。私はプログラムが自動的にファイルを生成する方法を探しています。オプションの名前とその価値を印刷することを意味します。例えば:

>./main init.cfg 
:その後、私は、テキストエディタを使用して値を変更し、そのファイルに移動して、このファイルを使用することになり、この

[wave packet] 
width = 1 
position = 2.0 
[calculation parameters] 
levels = 15 

のように見えるinit.cfgを生成するオプションなし

>./main 

これにアプローチするいい方法は、variables_mapにoperator<<を割り当てることです。私はこれをファイルに書き込むことができます。値を変更します。ファイルを読んでください。すべて同じ形式であり、各行を書き込む必要はありません。

ドキュメントや例にそのようなものが見つかりませんでした。可能であれば教えてください

EDIT:Sam Millerはセクション内でiniファイルを解析する方法を示しました。しかし、私はまだboost :: program_options :: variables_map VMから値を取得することに問題があります。 私は、代わりにit->second.value()次の

for(po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it) 
    { 
    if(it->first!="help"&&it->first!="config") 
    cout << "first - " << it->first << ", second - " << it->second.value() << "\n"; 
    } 

を試してみましたエラーを得ました。私もit->secondを試しました。私もエラーました:私はit->second.as<int>()を使用するすべてではなく、私の値の場合、私は正しく値を取得

icpc -lboost_serialization -lboost_program_options -c programOptions.cc 
programOptions.cc(60): error: no operator "<<" matches these operands 
      operand types are: std::basic_ostream<char, std::char_traits<char>> << boost::any 
     cout << "first - " << it->first << ", second - " << it->second.value() << "\n"; 
                ^

compilation aborted for programOptions.cc (code 2) 
make: *** [programOptions.o] Error 2 

をint型であり、私は二重に達すると、プログラムはこれでクラッシュ:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >' 
    what(): boost::bad_any_cast: failed conversion using boost::any_cast 

答えて

12

あります私が知っているprogram_optionsを使用する方法ではありません。あなたはwrite the ini fileにプロパティツリーライブラリを使うことができます。ここで

は短い例です:

macmini:stackoverflow samm$ cat property.cc 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/ini_parser.hpp> 

#include <iostream> 

int 
main() 
{ 
    using boost::property_tree::ptree; 

    ptree root; 

    ptree wave_packet; 
    wave_packet.put("width", "1"); 
    wave_packet.put("position", "2.0"); 

    ptree calculation_parameters; 
    calculation_parameters.put("levels", "15"); 

    root.push_front(
      ptree::value_type("calculation parameters", calculation_parameters) 
      ); 
    root.push_front(
      ptree::value_type("wave packet", wave_packet) 
      ); 

    write_ini(std::cout, root); 

    return 0; 
} 

macmini:stackoverflow samm$ g++ property.cc 
macmini:stackoverflow samm$ ./a.out 
[wave packet] 
width=1 
position=2.0 
[calculation parameters] 
levels=15 
macmini:stackoverflow samm$ 
+0

あなたは簡単な例を書くことができますか?それを行う方法をロードマップを与えるか? –

+0

@kirill_igum例を追加しました。 –

0

は、私の知る限りは質問を理解して、それが与えられたoption_descriptionに基づいて設定ファイルを作成する方法についてです。

ここに、可能な解決方法があります。これは、設定ファイルにoptions_descriptionを書き込む方法です。これは、すべてのパラメータにデフォルト値があることに関連しています。あなたが設定ファイルのセクションを必要とする場合に問題がある

algorithmsDesc_.add_options() 
    ("general.blur_Width", po::value<int>(&varWhereToStoreValue)->default_value(3), "Gaussian blur aperture width") 

void SaveDefaultConfig() 
{ 
    boost::filesystem::ofstream configFile(configFilePath_); 
    auto descOptions = algorithmsDesc_.options(); 
    boost::property_tree::ptree tree; 

    for (auto& option : descOptions) 
    { 
     std::string name = option->long_name(); 
     boost::any defaultValue; 
     option->semantic()->apply_default(defaultValue); 

     if (defaultValue.type() == typeid(std::string)) 
     { 
      std::string val = boost::any_cast<std::string>(defaultValue); 
      tree.put(name, val); 
     } 
     ///Add here additional else.. type() == typeid() if neccesary 
    } 

    //or write_ini 
    boost::property_tree::write_json(configFile, tree); 
} 

はここalgorithmsDescはあなたのようなオプションを説明どこつまり、後押し:: program_optionsを:: options_descriptionです。 options_descriptionには、そのコンストラクタを介してキャプションを渡すメソッドがありません。それを得る汚い方法は、print()によって作られた出力ストリームから切り取ることです。

それらを一緒に組み合わせることは簡単です。

関連する問題