C++: configuration file

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Cette page est une traduction de la page C++ : fichier de configuration et la traduction est complétée à 100 % et à jour.

Autres langues :anglais 100% • ‎français 100%

The Configuration class presented here can read and keep values of any configuration file written in a format like this:

#
# Simulation parameters
#
 
nbDimensions    = 2
temperature     = 25.001
epsilon         = 1.013e-14
writeLogFile    = false      # NOTE: Set to "true" in debug mode only.
                             #       Logging slows down the program.
errorMessage    = the simulation failed

This format is very flexible and easy to organize. Some advantages:

  • you can insert white space (empty lines, spaces, and tabs) to make the file more readable;
  • the order of variables is not important;
  • you can write comments anywhere, which start with a number sign (#).

The class is based on the STL (Standard Template Library) std::map<T> container. This container, called associative, stores data in the form of key-value pairs. It is analogue to a telephone directory: the key (the name) is used to find the value (the telephone number).

File : configuration.cpp
#include <map>
#include <string>
#include <fstream>
#include <iostream>
 
using namespace std;
 
class Configuration
{
public:
    // clear all values
    void Clear();
 
    // load a configuration file
    bool Load(const string& File);
 
    // check if value associated with given key exists
    bool Contains(const string& key) const;
 
    // get value associated with given key
    bool Get(const string& key, string& value) const;
    bool Get(const string& key, int&    value) const;
    bool Get(const string& key, long&   value) const;
    bool Get(const string& key, double& value) const;
    bool Get(const string& key, bool&   value) const;
 
private:
    // the container
    map<string,string> data;
 
    // remove leading and trailing tabs and spaces
    static string Trim(const string& str);
};
 
 
// ----------------------------------
// method implementations
// ----------------------------------
 
void Configuration::Clear()
{
    data.clear();
}
 
bool Configuration::Load(const string& file)
{
    ifstream inFile(file.c_str());
 
    if (!inFile.good())
    {
        cout << "Cannot read configuration file " << file << endl;
        return false;
    }
 
    while (inFile.good() && ! inFile.eof())
    {
        string line;
        getline(inFile, line);
 
        // filter out comments
        if (!line.empty())
        {
            int pos = line.find('#');
 
            if (pos != string::npos)
            {
                line = line.substr(0, pos);
            }
        }
 
        // split line into key and value
        if (!line.empty())
        {
            int pos = line.find('=');
 
            if (pos != string::npos)
            {
                string key     = Trim(line.substr(0, pos));
                string value   = Trim(line.substr(pos + 1));
 
                if (!key.empty() && !value.empty())
                {
                    data[key] = value;
                }
            }
        }
    }
 
    return true;
}
 
bool Configuration::Contains(const string& key) const
{
    return data.find(key) != data.end();
}
 
bool Configuration::Get(const string& key, string& value) const
{
    map<string,string>::const_iterator iter = data.find(key);
 
    if (iter != data.end())
    {
        value = iter->second;
        return true;
    }
    else
    {
        return false;
    }
}
 
bool Configuration::Get(const string& key, int& value) const
{
    string str;
 
    if (Get(key, str))
    {
        value = atoi(str.c_str());
        return true;
    }
    else
    {
        return false;
    }
}
 
bool Configuration::Get(const string& key, long& value) const
{
    string str;
 
    if (Get(key, str))
    {
        value = atol(str.c_str());
        return true;
    }
    else
    {
        return false;
    }
}
 
bool Configuration::Get(const string& key, double& value) const
{
    string str;
 
    if (Get(key, str))
    {
        value = atof(str.c_str());
        return true;
    }
    else
    {
        return false;
    }
}
 
bool Configuration::Get(const string& key, bool& value) const
{
    string str;
 
    if (Get(key, str))
    {
        value = (str == "true");
        return true;
    }
    else
    {
        return false;
    }
}
 
string Configuration::Trim(const string& str)
{
    int first = str.find_first_not_of(" \t");
 
    if (first != string::npos)
    {
        int last = str.find_last_not_of(" \t");
 
        return str.substr(first, last - first + 1);
    }
    else
    {
        return "";
    }
}


Example how to use it:

File : configuration_example.cpp
Configuration   config;
int             nbDimensions;
double          temperature;
double          epsilon;
bool            writeLogFile;
string          errorMessage;
 
config.Load("./simulation.cfg");
 
if (config.Get("nbDimensions", nbDimensions)    &&
    config.Get("temperature",  temperature)     &&
    config.Get("epsilon",      epsilon)         &&
    config.Get("writeLogFile", writeLogFile)    &&
    config.Get("errorMessage", errorMessage))
{
    ...
}
else
{
    cout << "Missing parameter in configuration file." << endl;
}


Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager