Configuration File Parser
Overview
cfg_parser is a robust configuration file parser written in C++. It can read and write configuration files preserving any comments made inside the file. It supports escaped characters, quoted text and infinite line length (a whole line must fit into an STL string).
Features
- keyword = value
- [Sections]
- # comments
- [Sections] # with comments
- keyword = value # pairs with comments
- keyword = „values with spaces, newlines \n, embedded quotes \“ and all other escape characters supported by printf„
- sloppy parsing:
keyword= value
is accepted as well askeyword=value
orkeyword value
(withouth '=') - displays parsing errors in a human friendly format (including filename, line number and line contents in question)
Download
Code Example
#include <iostream> #include <string> #include "cfg_parser.h" using namespace std; int main(int argc, char *argv[]) { ConfigParser cfg("test.cfg"); cfg.debug(); cfg.writeFile("test2.cfg"); int i = cfg.get("hier", -1); cout << "global hier=" << i << endl; i = cfg.get("hier", 0, "section"); cout << "section hier=" << i << endl; string value = cfg.get<string>("testvar", "..not found.."); cout << "value: " << value << endl; value.clear(); // alternative way string value2; cfg.getVar("testvar", value2); cout << "value: " << value << " value2: " << value2 << endl; // C strings need an extra function to return a const pointer to the saved element // REMARK: the const char* is valid only as long as the keyword exists!! test = cfg.getCString("testvar", "bla"); test2 = cfg.getCString("testvar", ""); test3 = cfg.getCString("testvar", ""); printf("test: %s test2: %s test3: %s\n", test, test2, test3); //cfg.delVar("testvar"); cfg.getCString("keyword"); cfg.getCString("bal"); cfg.getCString("bla"); printf("test: %s test2: %s test3: %s\n", test, test2, test3); // Creating a completely new config file ConfigParser t; t.set<int>("value 1 b", 25); t.set("time", 300); t.set("angle", 2.5334); t.set("text", "welcome\nall your bayes"); char* text = "hlablablablabl"; t.set("text2", text); t.writeFile("new.cfg"); ConfigParser b("new.cfg"); b.debug(); return 0; }
Documentation
Only relevant members are shown!
class ConfigParser { public: ConfigParser(const std::string& in_file = ""); ~ConfigParser(); // loads the given configuration file int readFile(const std::string& in_file); // writes the current configuration to the given file. I file not given, write back into the inputfile int writeFile(const std::string& out_file = ""); // returns filname of loaded file void getFilename(std::string& in_file); // empty lines in config file are written back to the out_file if enable = true. // this function has to be called before readFile() since it defaults to false void preserveEmptyLines(bool enable = true); // return variable from configuration (if non-existent, value remains unchanged) void getVar(const std::string& keyword, std::string& value, const std::string& section = ""); // sets variable in configuration (section and/or variable are added if non-existent) // if keyword is "-" then comment is appended to the given section. It is not possible to change the comment afterwards void setVar(const std::string& keyword, const std::string& value, const std::string& section = "", const std::string& comment = ""); // deletes variable from configuration void delVar(const std::string& keyword, const std::string& section = ""); // returns value converted to type T if found, default_value else // Remark: does NOT work with char*. Use std::string or getCString() instead template <typename T> T get(const std::string& keyword, const T& default_value, const std::string& section = ""); // set value of keyword (internally converted to string). (works with char* too) template <typename T> void set(const std::string& keyword, const T& value, const std::string& section = ""); // returns const char* if found c_str() of supplied default_value else. Remark that char* is only valid as long as keyword exists! const char* getCString(const std::string& keyword, const char* default_value = NULL, const std::string& section = ""); // adds a section to the configuration (if it does not yet exist) void addSection(const std::string& section, const std::string& comment = ""); // deletes a section (if it exists) void delSection(const std::string& section); // displays current configuration content using cout void debug(); };
Example Config File
The following file is read-in correctly.
# Test file for cfg_parser # lets begin with a comment.. well we already did :-) # simple stuff keyword = value bla=123 test 234 text = "my loooong text including nested \" ! and line\nbreaks\n." # little bit more complicated bal = asdfasdfas text2="blaaaldflkadf"#evil comment text3 = "lets try a note that lasts for more than a line" # and including a comment :-) # another comment # yet another comment adf = adfasdf #bla a dffff [mysection] hier = 1 hier = 2 [ a ] adf adsf [ asdf d] a asdfdf
License
<html>
<!– Creative Commons License –> <a href=„http://creativecommons.org/licenses/GPL/2.0/“> <img alt=„CC-GNU GPL“ border=„0“ src=„http://creativecommons.org/images /public/cc-GPL-a.png“ /></a><br /> This software is licensed under the <a href=„http://creativecommons.org/licenses/GPL/2.0/“>CC-GNU GPL</a>. <!– /Creative Commons License –>
<!–
<rdf:RDF xmlns=„http://web.resource.org/cc/“
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about=“„>
<license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:type rdf:resource="http://purl.org/dc/dcmitype/Software" />
</Work>
<License rdf:about=„http://creativecommons.org/licenses/GPL/2.0/“> <permits rdf:resource=„http://web.resource.org/cc/Reproduction“ />
<permits rdf:resource="http://web.resource.org/cc/Distribution" /> <requires rdf:resource="http://web.resource.org/cc/Notice" /> <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <requires rdf:resource="http://web.resource.org/cc/SourceCode" />
</License>
</rdf:RDF>
–>
</html>