How to parse ini file with boost

I have an ini file containing some sample values, for example:

[Section1] Value1 = 10 Value2 = a_text_string 

I am trying to download these values ​​and print them in my application using Boost, but I don’t understand how to do this in C ++.

I searched this forum to find a few examples (I always used C, and therefore I am not very good in C ++), but I only found examples of how to read values ​​from a file all at once.

I need to load only one value when I want, for example string = Section1.Value2 , because I do not need to read all the values, but only some of them.

I would like to load individual values ​​and store them in a variable so I can use them whenever I want in my application.

Can this be done with Boost?

I am currently using this code:

 #include <iostream> #include <string> #include <set> #include <sstream> #include <exception> #include <fstream> #include <boost/config.hpp> #include <boost/program_options/detail/config_file.hpp> #include <boost/program_options/parsers.hpp> namespace pod = boost::program_options::detail; int main() { std::ifstream s("file.ini"); if(!s) { std::cerr<<"error"<<std::endl; return 1; } std::set<std::string> 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 << i->value[0] << std::endl; } 

But it just read all the values ​​in the for loop; on the contrary, I just want to read single values ​​when I want, and I don’t need to insert the values ​​into the file, because it is already written with all the values ​​that I need in my program.

+57
c ++ boost parsing ini
May 30 '11 at 11:09 a.m.
source share
4 answers

You can also use Boost.PropertyTree to read .ini files:

 #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ini_parser.hpp> ... boost::property_tree::ptree pt; boost::property_tree::ini_parser::read_ini("config.ini", pt); std::cout << pt.get<std::string>("Section1.Value1") << std::endl; std::cout << pt.get<std::string>("Section1.Value2") << std::endl; 
+122
May 30 '11 at 12:38
source share

Parsing INI files is easy because of their simple structure. Using AX, I can write several lines to analyze sections, properties, and comments:

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

A more detailed example can be found in Reference.pdf

As for not reading the whole file, this can be done in different ways. First of all, the parser for the INI format requires at least forwarding iterators, so you cannot use stream iterators because they are input iterators. You can create a separate class for the stream with the required iterators (I wrote one such class in the past with a sliding buffer). You can use a memory mapped file. Or you can use a dynamic buffer, read from a standard stream and feed to the parser until you find a value. If you do not want to have a real parser and do not care if the structure of the INI files is correct or not, you can simply search for your tokens in the file. For this, input iterators are enough.

Finally, I'm not sure that avoiding reading the entire file will bring any benefits. INI files are usually quite small, and since the hard drive and several buffering systems will in any case read one or more sectors (even if you need only one byte), so I doubt there will be any kind of performance improvement, trying partially read the file (especially by doing it multiple times), possibly vice versa.

+4
Jun 01 2018-11-11T00:
source share

I read a good article on INI parsing using boost methods, he called an INI file reader using the Silviu Simen spirit library .

It is simple.

+2
Jun 22 '11 at 8:12
source share

The file must be parsed, which must be done sequentially. So I just read the whole file, saved all the values ​​in some collection ( map or unordered_map , perhaps either using pair<section, key> as the key, or using the map of the maps) and pulled them out where necessary.

+1
May 30 '11 at 11:33
source share



All Articles