2013-02-26 17 views
11

Program_options içinde multiple_sources.cpp örnek dosyasında gösterilen şekilde bir yapılandırma dosyasını standart olarak
olarak ayrıştırmak için Boost program_options kullanıyorum.Yükseltme parse_config_file, boş anahtar değeri

ifstream ini_file("config.ini"); 
    po::store(po::parse_config_file(ini_file, desc, true), vm); 
    po::notify(vm); 

config.ini dosya = gibi değer çiftleri boş bir anahtar ancak etti:

key1=value1 
key2=value2 
key3= 
key4= 
key5=value5 

Boost hata Bu dosya sonucu almak için çalışıyorum:

boost::program_options::invalid_option_value 

orada bir mi mekanizma boost :: program_options boş girişleri ile böyle yapılandırma dosyalarını okumak için?

Herhangi bir yardım çok takdir edilecektir. Bu sorun, henüz çözülmediğinden, bu Sorunu düzenliyorum. Örneği Boost'tan (1.53) alıntılayacağım.

Bu tam multiple_sources.cpp dosyasıdır:

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

Ve karşılık gelen yapılandırma dosyası (multiple_sources.cfg) 'dir:

: Şimdi bu dosyayı modifiye edilir

# 
# Comment out this line to use hard-coded default value of 10 
# 
optimization = 1 
include-path = /opt 

ise

# 
# Comment out this line to use hard-coded default value of 10 
# 
optimization = 
include-path = /opt 

Aşağıdaki hata iletisine atılmıştır:

vb aşırı doğrulama
the argument for option 'optimization' is invalid 

önerilen çözümler, bir '\ N' diğer beyaz boşluk tanıyan olasılığını içeren, her bir veri türü için bir onaylama işlevini yazmak zorunda olabilir, özellikle de gereksiz yere karmaşık görünmektedir.

Herhangi bir öneriniz var mı? Zaman ayırdığınız için herkese teşekkür ederim.

  ("optimization", po::value<int>(&opt)->zero_tokens(), 
        "optimization level") 

ve:

  ("optimization", po::value<int>(&opt)->implicit_value(10), 
        "optimization level") 

ve ikisi de boş okumak aşağıdaki

  ("optimization", po::value<int>(&opt)->default_value(10), 
        "optimization level") 

: Aditya önerisi sonrasında


Ben aşağıdaki satırı yerini almıştır seçenekler. aşağıdaki gibi örnek programı Boost "parser_test.cpp" bir vektör içerisine anahtar-değer çiftleri okuyarak zero_tokens() veya implicit_value() kullanımını atlar:

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"); 
} 
+0

Şunlara bir göz atın: http://stackoverflow.com/questions/4459650/skipping-unknown-options-without-throwing-with-boost-program-options – ypnos

+0

Link ypnos için teşekkürler, ancak ben zaten bir göz attım Bu çözümde parse_config_file argümanlarındaki 3. parametre olarak "true" ekledim. Bu hala sorunu çözmüyor. Bu problemle karşılaştın ve önerilen çözüm bunu düzeltti mi? –

+0

Üzgünüm, o zaman senin için yardım etmiyorum. :/ Eğer config dosyasında key3 = 1, key4 = 1 olsaydı işe yarar mı? – ypnos

cevap

1

Ben denemede ile çevrelemek için tavsiye ederim/Bu istisnayı yakalayın ve sadece programınız için gerçekten gerekli olan ve boş bırakılamayan alanlar için hatalar atın, aksi halde alan yoksayılır.

1

Hayır, şu anda boost :: program_options içinde bununla başa çıkmanın yolu yoktur. Boş bir tuşa sahip olmanız: INI dosyanızdaki değer çifti, argümanı sağlamadan komut satırındaki seçeneği belirtmekle aynıdır. Ypnos tarafından önerilen özel doğrulayıcıların yazım yönergesi işe yarayabilir, ancak beklediğiniz her seçeneğe uygulamanız gerekeceği için pratik değildir. Aradığınız sonucu elde etmek için po :: parse_config_file uygulamasının kendi değerini yazmanız gerekecek (ilgili seçenek sıfır_token olarak işaretlenmedikçe).

+0

Aslında, program_options [implicit_value()] 'yi kullanarak bir argüman olmadan komut satırında bir seçenek belirtmeyi sağlar (http://www.boost.org/doc/libs/1_43_0/doc/html/boost/program_options/typed_value .html # id887054-bb) yardımcı. Ama bu ne yazık ki INI dosyaları için çalışmıyor. –

İlgili konular