2

I have a configuration file myCfg.cfg that looks like this :

keyA = 1.0
keyB = 2
keyC = "hello"

Note that all the settings are at the root of the configuration tree.

I want my C++ program to load that file then add a new setting whose key is keyD and assign it integer value 5. Eventually, MyCfg should look like this in memory :

keyA = 1.0
keyB = 2
keyC = "hello"
keyD = 5

First the myCfg.cfg file is loaded to construct MyCfg. Then the setting keyD must be added to the root of MyCfg. The libconfig documentation indicates that the Setting::add() method :

add[s] a new child setting with the given name and type to the setting, which must be a group

However, there isn't any group in MyCfg… So how do I add a setting to the root of a Config object ?

Gael Lorieul
  • 3,006
  • 4
  • 25
  • 50
  • @Gluttton I am not sure what you mean by "have you saved settings?". First I construct a `Config` instance by reading configuration from a *.cfg file, then I take that `Config` object and I try to add a setting to it. I never attempt to write a new *.cfg file that would correspond to the inputted *.cfg file plus an extra setting. – Gael Lorieul Jan 28 '16 at 10:38
  • @Gluttton no I did not call `writeFile()` nor do I intend to do so. Here is more info on the context : I use a `Config` object as a collection of parameters for running my code. There are two similar routines in the code : in the first, a parameter must be chosen by the user by specifying a setting in the *.cfg file. In the other, only a single value for that parameter makes sense. Therefore, to hide it from the user I require him/her to write a configuration file without that setting and the code has to add it afterwards. – Gael Lorieul Jan 28 '16 at 10:54

1 Answers1

2

It looks like all what you need is: getRoot ().

Here is example:

#include <iostream>
#include "libconfig.h++"


int main ()
{
    libconfig::Config MyCfg;
    std::string file = "myCfg.cfg";

    try {
        MyCfg.readFile (file.c_str () );

        libconfig::Setting & root = MyCfg.getRoot ();
        // This also works.
        // libconfig::Setting & root = MyCfg.lookup ("");
        libconfig::Setting & keyD = root.add ("KeyD", libconfig::Setting::TypeInt);
        keyD = 5;

        // You dont need it, but it's just for testing.
        MyCfg.writeFile (file.c_str () );
    }
    catch (...) {
        std::cout << "Error caused!" << std::endl;
    }

    return 0;
}
Gluttton
  • 5,739
  • 3
  • 31
  • 58
  • 1
    Yes, thank you ! (Damn, that was in example/example2.cpp… RTFM to myself…) – Gael Lorieul Jan 28 '16 at 11:23
  • After making it work with `getRoot()` I realised that `libconfig::Setting & root = MyCfg.getRoot()` can be replaced either by ``libconfig::Setting & root = MyCfg.lookup("")` or by `libconfig::Setting & root = MyCfg.getRoot(".")`. All three work even-though `getRoot()` is by far the most elegant ! Perhaps you would like to add this remark to your answer ? I think there must have been a bug in my code and it got me confused… I edited my question in consequence. Once again, thanks for the help ! – Gael Lorieul Jan 28 '16 at 11:43
  • I've added remark to my answer about `lookup ("")`. But version `MyCfg.getRoot(".")` doesn't work for my (I can't compile it and it's and this corresponds to the documentation, because there are not version `getRoot` with parameters). – Gluttton Jan 28 '16 at 13:43
  • My mistake : it was `MyCfg.lookup(".")`, not `MyCfg.getRoot(".")` – Gael Lorieul Jan 28 '16 at 16:01