Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a simple configuration file and parser in C++

I am trying to create a simple configuration file that looks like this

url = http://mysite.com file = main.exe true = 0 

when the program runs, I would like it to load the configuration settings into the programs variables listed below.

string url, file; bool true_false; 

I have done some research and this link seemed to help (nucleon's post) but I can't seem to get it to work and it is too complicated to understand on my part. Is there a simple way of doing this? I can load the file using ifstream but that is as far as I can get on my own. Thanks!

like image 879
llk Avatar asked Jul 31 '11 22:07

llk


People also ask

What is configuration file example?

Configuration files have largely adopted a serialization format, such as XML, YAML and JSON, to represent complex data structures in a way that is easily stored and parsed. The resulting filenames can reflect the format. For example, a configuration file in YAML format may appear such as myapplication_configuration.

What is configuration parsing?

ConfigParser is a Python class which implements a basic configuration language for Python programs. It provides a structure similar to Microsoft Windows INI files. ConfigParser allows to write Python programs which can be customized by end users easily.


Video Answer


2 Answers

In general, it's easiest to parse such typical config files in two stages: first read the lines, and then parse those one by one.
In C++, lines can be read from a stream using std::getline(). While by default it will read up to the next '\n' (which it will consume, but not return), you can pass it some other delimiter, too, which makes it a good candidate for reading up-to-some-char, like = in your example.

For simplicity, the following presumes that the = are not surrounded by whitespace. If you want to allow whitespaces at these positions, you will have to strategically place is >> std::ws before reading the value and remove trailing whitespaces from the keys. However, IMO the little added flexibility in the syntax is not worth the hassle for a config file reader.

const char config[] = "url=http://example.com\n"                       "file=main.exe\n"                       "true=0";  std::istringstream is_file(config);  std::string line; while( std::getline(is_file, line) ) {   std::istringstream is_line(line);   std::string key;   if( std::getline(is_line, key, '=') )   {     std::string value;     if( std::getline(is_line, value) )        store_line(key, value);   } } 

(Adding error handling is left as an exercise to the reader.)

like image 70
sbi Avatar answered Sep 23 '22 14:09

sbi


As others have pointed out, it will probably be less work to make use of an existing configuration-file parser library rather than re-invent the wheel.

For example, if you decide to use the Config4Cpp library (which I maintain), then your configuration file syntax will be slightly different (put double quotes around values and terminate assignment statements with a semicolon) as shown in the example below:

# File: someFile.cfg url = "http://mysite.com"; file = "main.exe"; true_false = "true"; 

The following program parses the above configuration file, copies the desired values into variables and prints them:

#include <config4cpp/Configuration.h> #include <iostream> using namespace config4cpp; using namespace std;  int main(int argc, char ** argv) {     Configuration *  cfg = Configuration::create();     const char *     scope = "";     const char *     configFile = "someFile.cfg";     const char *     url;     const char *     file;     bool             true_false;      try {         cfg->parse(configFile);         url        = cfg->lookupString(scope, "url");         file       = cfg->lookupString(scope, "file");         true_false = cfg->lookupBoolean(scope, "true_false");     } catch(const ConfigurationException & ex) {         cerr << ex.c_str() << endl;         cfg->destroy();         return 1;     }     cout << "url=" << url << "; file=" << file          << "; true_false=" << true_false          << endl;     cfg->destroy();     return 0; } 

The Config4Cpp website provides comprehensive documentation, but reading just Chapters 2 and 3 of the "Getting Started Guide" should be more than sufficient for your needs.

like image 37
Ciaran McHale Avatar answered Sep 22 '22 14:09

Ciaran McHale