2011-01-16 4 views
12

Ich verwende boost :: program_options, um Parameter aus einer Konfigurationsdatei zu erhalten.gibt es eine Möglichkeit, Config-Datei für Boost-Programmoptionen zu drucken

ich verstehe, dass ich eine Datei von Hand erstellen kann und Programmoptionen werden es analysieren. aber ich suche nach einer Möglichkeit für das Programm, die Datei automatisch zu generieren. das bedeutet, den Namen der Option und ihren Wert auszudrucken. zum Beispiel:

>./main 

ohne Option würde init.cfg erzeugen, die i

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

dann in diese Datei gehen die Werte ändern Texteditor sieht wie folgt aus und verwenden diese Datei:

>./main init.cfg 

eine gute Möglichkeit, dies zu erreichen, wäre Variablen_map operator<< zu haben. Auf diese Weise kann ich es einfach in die Datei schreiben. Ändern Sie die Werte. lies die Datei. alle im selben Format und müssen nicht jede Zeile schreiben.

Ich konnte nichts dergleichen in der Dokumentation oder Beispielen finden. Bitte lass es mich wissen, wenn dies möglich ist

EDIT: Sam Miller zeigte, wie die Ini-Datei in Abschnitten zu analysieren. Ich habe jedoch immer noch ein Problem, die Werte von boost :: program_options :: variables_map vm zu bekommen. Ich habe versucht, die folgende

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"; 
    } 

statt it->second.value(), bekam einen Fehler. Ich versuchte auch it->second. Ich habe auch einen Fehler:

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 

bekomme ich den Wert korrekt, wenn ich it->second.as<int>() verwenden, aber nicht alle meine Werte sind ints und sobald ich doppelt erreichen, stürzt das Programm mit diesem:

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 

Antwort

12

Es gibt Ich benutze keine programmoptionen, die mir bekannt sind. Sie können die Eigenschaftsbaumbibliothek zu write the ini file verwenden.

Hier ist ein kurzes Beispiel:

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

Gibt es eine Möglichkeit, ein kurzes Beispiel zu schreiben? oder geben Sie eine Straßenkarte, wie es geht? –

+0

@kirill_igum Ich habe ein Beispiel hinzugefügt. –

0

Soweit ich verstehe die Frage, es geht darum, wie Konfigurationsdatei schreibt auf gegebene option_description basierte.

Hier ist die mögliche Lösung, wie man eine options_description in die Konfigurationsdatei schreibt. Es bezieht sich auf die Tatsache, dass jeder Parameter einen Standardwert hat.

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); 
} 

Hier algorithmsDesc ist boost :: program_options :: options_description, das ist, wo Sie die Optionen beschreiben wie:

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

Das Problem ist, wenn Sie Abschnitte in der Konfigurationsdatei benötigen. options_description verfügt nicht über eine Methode zum Abrufen von Untertiteln, die durch den Konstruktor übergeben werden. Die schmutzige Art und Weise zu erhalten, ist es von dem Ausgangsstrom durch Druck gemacht zu schneiden():

std::string getSectionName() 
{ 
    std::stringstream ss; 
    algorithmDesc_.print(ss) 

    std::string caption; 
    std::getline(ss,caption) 

    //cut last ':' 
    return caption.substr(0, caption.size() - 1) 
} 

Kombinieren sie zusammen unkompliziert.