Como analisar o arquivo ini com o Boost

Eu tenho um arquivo ini que contém alguns valores de amostra como:

[Section1] Value1 = 10 Value2 = a_text_string 

Estou tentando carregar esses valores e imprimi-los no meu aplicativo com Boost, mas não entendo como fazer isso em C ++.

Procurei neste fórum para encontrar alguns exemplos (sempre usei C e não sou muito bom em C ++), mas encontrei apenas exemplos sobre como ler valores de um arquivo de uma só vez.

Eu preciso carregar apenas um único valor quando eu quero, como string = Section1.Value2 porque eu não preciso ler todos os valores, mas apenas alguns deles.

Gostaria de carregar valores únicos e armazená-los na variável, a fim de usá-los quando eu quiser no meu aplicativo.

É possível fazer isso com o Boost?

No momento, estou usando este código:

 #include  #include  #include  #include  #include  #include  #include  #include  #include  namespace pod = boost::program_options::detail; int main() { std::ifstream s("file.ini"); if(!s) { std::cerr<<"error"<<std::endl; return 1; } std::set options; options.insert("Test.a"); options.insert("Test.b"); options.insert("Test.c"); for (boost::program_options::detail::config_file_iterator i(s, options), e ; i != e; ++i) std::cout <value[0] << std::endl; } 

Mas isso apenas lê todos os valores em um loop for ; pelo contrário, eu só quero ler valores individuais quando eu quero e não preciso inserir valores no arquivo, porque ele já está escrito com todos os valores que eu preciso no meu programa.

Você também pode usar o Boost.PropertyTree para ler arquivos .ini:

 #include  #include  ... boost::property_tree::ptree pt; boost::property_tree::ini_parser::read_ini("config.ini", pt); std::cout << pt.get("Section1.Value1") << std::endl; std::cout << pt.get("Section1.Value2") << std::endl; 

Analisar arquivos INI é fácil devido à sua estrutura simples. Usando o AX, posso escrever algumas linhas para analisar seções, propriedades e comentários:

 auto trailing_spaces = *space & endl; auto section = '[' & r_alnumstr() & ']'; auto name = +(r_any() - '=' - endl - space); auto value = '"' & *("\\\"" | r_any() - '"') & '"' | *(r_any() - trailing_spaces); auto property = *space & name & *space & '=' & *space & value & trailing_spaces; auto comment = ';' & *(r_any() - endl) & endl; auto ini_file = *comment & *(section & *(prop_line | comment)) & r_end(); 

Um exemplo mais detalhado pode ser encontrado no Reference.pdf

Em relação a não ler todo o arquivo, isso pode ser feito de diferentes maneiras. Em primeiro lugar, o analisador para o formato INI requer pelo menos iteradores de encaminhamento, portanto, você não pode usar iteradores de stream, já que eles são iteradores de input. Você pode criar uma class separada para stream com iteradores necessários (eu escrevi uma class no passado com buffer de deslizamento). Você pode usar o arquivo mapeado de memory. Ou você pode usar um buffer dynamic, lendo o stream padrão e fornecendo ao analisador até encontrar os valores. Se você não quer ter um analisador real, e não se importa se a estrutura do arquivo INI está correta ou não, você pode simplesmente procurar seus tokens no arquivo. Input iterators seria suficiente para isso.

Por fim, não tenho certeza de que evitar ler todo o arquivo traz vantagens. Os arquivos INI são tipicamente muito pequenos, e como o disco rígido e múltiplos sistemas de buffer lêem um ou mais setores de qualquer maneira (mesmo que você precise de apenas um byte), então duvido que houvesse alguma melhoria de desempenho tentando ler arquivos parcialmente (especialmente fazendo repetidamente), provavelmente o oposto.

Eu li um bom artigo sobre o INI-parsing com methods de reforço, chamado de leitor de arquivos INI usando a biblioteca espiritual de Silviu Simen .

É simples.

O arquivo precisa ser analisado, o que deve ser feito seqüencialmente. Então, eu acabei de ler o arquivo inteiro, armazenar todos os valores em alguma coleção ( map ou unordered_map , provavelmente, usando o pair como chave ou usando o mapa de mapas) e buscá-los quando necessário.