How to parse ini file with Boost
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;
c++ boost parse ini file when containing multikeys
Your input is simply not an INI file, as INI files do not permit duplicate values. You can write your own parser, e.g. using the code I wrote here:¹
- Cross-platform way to get line number of an INI file where given option was found
If you replace the section_t
map
typedef std::map<textnode_t, textnode_t> section_t;
with multimap
:
typedef std::multimap<textnode_t, textnode_t> section_t;
you can parse repeated keys:
[section_1]
key_1=value_1
key_1=value_2
key_n=value_n
[section_2]
key1=value_1
key2=value_2
key_n=value_1
key_n=value_2
[section_n]
See full code here: https://gist.github.com/sehe/068b1ae81547b98a3cec02a530f220df
¹ or Learning Boost.Spirit: parsing INI and http://coliru.stacked-crooked.com/view?id=cd1d516ae0b19bd6f9af1e3f1b132211-0d2159870a1c6cb0cd1457b292b97230 and possibly others
How to read and write .ini files using boost library
With Boost.PropertyTree
you can read and update the tree, then write to a file (see load
and save
functions.
Have a look at How to access data in property tree.
You can definitely add new property or update existing one.
It mentiones that there's erase
on container as well so you should be able to delete existing value. Example from boost
(link above):
ptree pt;
pt.put("a.path.to.float.value", 3.14f);
// Overwrites the value
pt.put("a.path.to.float.value", 2.72f);
// Adds a second node with the new value.
pt.add("a.path.to.float.value", 3.14f);
I would assume you would then write updated tree into a file, either new one or overwrite existing one.
EDIT :
For ini file it does specific checks.
The above example if you try to save to ini with ini_parser you get:
- ptree is too deep
- duplicate key
With that fixed here is an example code that writes ini file, I've updated a value of existing key then added a new key:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
void save(const std::string &filename)
{
using boost::property_tree::ptree;
// pt.put("a.path.to.float.value", 3.14f);
// pt.put("a.path.to.float.value", 2.72f);
// pt.add("a.path.to.float.value", 3.14f);
ptree pt;
pt.put("a.value", 3.14f);
// Overwrites the value
pt.put("a.value", 2.72f);
// Adds a second node with the new value.
pt.add("a.bvalue", 3.14f);
write_ini( filename, pt );
}
int main()
{
std::string f( "test.ini" );
save( f );
}
the test.ini
file:
[a]
value=2.72
bvalue=3.14
Feel free to experiment.
Reading INI file using Boost Property Tree when value section does not exist
Using Boost.Optional
:
s = pt.get_optional<std::string>("Section1.value1").get_value_or("default");
// ^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^
iterate over ini file on c++, probably using boost::property_tree::ptree?
To answer your question directly: of course iterating a property tree is possible. In fact it's trivial:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
int main()
{
using boost::property_tree::ptree;
ptree pt;
read_ini("input.txt", pt);
for (auto& section : pt)
{
std::cout << '[' << section.first << "]\n";
for (auto& key : section.second)
std::cout << key.first << "=" << key.second.get_value<std::string>() << "\n";
}
}
This results in output like:
[Cat1]
name1=100 #skipped
name2=200 \#not \\skipped
name3=dhfj dhjgfd
[Cat_2]
UsagePage=9
Usage=19
Offset=0x1204
[Cat_3]
UsagePage=12
Usage=39
Offset=0x12304
I've written a very full-featured Inifile parser using boost-spirit before:
- Cross-platform way to get line number of an INI file where given option was found
It supports comments (single line and block), quotes, escapes etc.
(as a bonus, it optionally records the exact source locations of all the parsed elements, which was the subject of that question).
For your purpose, though, I think I'd recomment Boost Property Tree.
How to parse more than 2 level ini file with Boost
INI files do not support structure like this. If you want to have different structural levels in an INI file, you have to specify the full path in each section:
[Section1]
Value1 = 10
Value2 = a_text_string
[Section2.SubSection1]
Value1=1
Value2=2
[Section2.SubSection2]
Value1=a
Value2=b
The actual "Section2." prefix means nothing specific in the INI grammar, it's just a way for you to create this kind of structure in a language that doesn't support it via nesting.
Related Topics
Check Variadic Templates Parameters for Uniqueness
Variadic Function Template with Pack Expansion Not in Last Parameter
How to Add a Timed Delay to a C++ Program
Convert String Containing Several Numbers into Integers
Call to Pure Virtual Function from Base Class Constructor
Detecting the Parameter Types in a Spirit Semantic Action
Are Vectors Passed to Functions by Value or by Reference in C++
Why Are Null Pointers Defined Differently in C and C++
Confusion Between C++ and Opengl Matrix Order (Row-Major VS Column-Major)
Structure of a C++ Object in Memory VS a Struct
Case Insensitive Std::String.Find()
How to Recover View Space Position Given View Space Depth Value and Ndc Xy