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!
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.
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.
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With