使用libconfig导入数组或列表设置

时间:2017-08-25 22:04:10

标签: c++ configuration configuration-files libconfig

我之前从未真正使用过配置文件,但我有兴趣使用一个作为我正在编写的工程代码的参数文件。

不是专业程序员,我花了两天时间试图找出如何使用libconfig导入一个简单的列表或数组设置,我似乎无法到达任何地方。大致从example here开始工作,我能够成功导入标量设置,比如

(importtest.cfg)

mynumber = 1;

使用像

这样的主要功能
  Config cfg;

  // check for I/O and parse errors
  try
    {
      cfg.readFile("importtest.cfg");
    }
  catch(const FileIOException &fioex)
    {
      std::cerr << "I/O error while reading config file." << std::endl;
      return(EXIT_FAILURE);
    }
  catch(const ParseException &pex)
    {
      std::cerr << "Parse error at " << pex.getFile() << " : line " << pex.getLine() << " - " << pex.getError() << std::endl;
      return(EXIT_FAILURE);
    }

  // look for 'mynumber'
  try
    {
      int number = cfg.lookup("mynumber");
      std::cout << "your number is " << number << std::endl;
    }
  catch(const SettingNotFoundException &nfex)
    {
      std::cerr << "No 'mynumber' setting in configuration file." << std::endl;
    }

我得到了预期的输出

your number is 1

但我无法导入简单的列表设置,例如

mylist = (1,2,3,4);

以类似的方式。我已经尝试了许多解决方案(比如创建根设置),但是并不真正理解它们中的任何一个。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我还需要一段时间来解决这个问题。这就是我最终基于https://github.com/hyperrealm/libconfig/blob/master/examples/c%2B%2B/example1.cpp

的方式

example_simple.cfg文件:

albums  =
  (
    { 
      title      = "one title";
      year       = 2017;
      songs      = ["first song", "second song"];
    },
    { 
      title      = "another title";
      year       = 2015;
      songs      = ["first song", "second song", "third song"];
    }
  );

使用libconfig C ++ API读取它:

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <vector>
#include <libconfig.h++>

using namespace std;
using namespace libconfig;

int main(int argc, char **argv)
{
  Config cfg;

  // Read the file. If there is an error, report it and exit.
  try
  {
    cfg.readFile("../example_simple.cfg");
  }
  catch(const FileIOException &fioex)
  {
    std::cerr << "I/O error while reading file." << std::endl;
    return(EXIT_FAILURE);
  }
  catch(const ParseException &pex)
  {
    std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
              << " - " << pex.getError() << std::endl;
    return(EXIT_FAILURE);
  }

  const Setting& root = cfg.getRoot();
  try
  {
    const Setting &albums = root["albums"];
    for(int i = 0; i < albums.getLength(); ++i)
    {
      const Setting &album = albums[i];
      string my_title;
      int my_year;
      vector<string> my_songs;

      album.lookupValue("title", my_title);
      cout << "title: " << my_title << endl;
      album.lookupValue("year", my_year);
      cout << "year: " << my_year << endl;

      const Setting &songs_settings = album.lookup("songs");
      vector<string> songs;
      for (int n = 0; n < songs_settings.getLength(); ++n)
      {
          my_songs.push_back(songs_settings[i]);
          cout << "song number " << n << ": " << my_songs[n] << endl;
      }
    }
  }
  catch(const SettingNotFoundException &nfex)
  {
    // Ignore.
  }

  return(EXIT_SUCCESS);
}