SimpleIni
Cross platform programming can be painful, especially when it comes to simple tasks that you don’t want to think about because they aren’t your main problem. Unfortunately, it sometimes takes longer than it should to solve these tasks. One of these problems is loading configuration files. Although cross-platform XML libraries are available, if the user of your software is going to directly modify the file, it can be painful. The old Windows INI configuration file is a lasting file format that is easy for the user to understand and hard to get wrong.
This component is a C++ class that provides the ability to load an INI-style configuration file on both Windows and Linux/Unix. It is fast, simple, and source code using this component will compile unchanged on either OS. It supports both MBCS and Unicode builds on Windows, and can load UTF-8 or MBCS files on all platforms.
Features
- Public domain, free use in all software (including GPL and commercial)
- Multi-platform (Windows 95/98/ME/NT/2K/XP/2003, Linux, Unix)
- Loads and saves INI-style configuration files
- Liberal acceptance of file format
- Key/Values with no section
- Removal of whitespace around sections, keys, and values
- Optional case-insensitive sections and keys (for ASCII characters only)
- Supports both char or wchar_t programming interfaces
- Supports both MBCS (system locale) and UTF-8 file encodings
- System locale does not need to be UTF-8 on Linux/Unix to load UTF-8 file
- Support for non-ASCII characters in section, keys, values, and comments
- Support for non-standard character types or file encodings via user-written converter classes
- Support for adding/modifying values programmatically
Usage Summary
- Declare an instance of the appropriate class. Note that the following definitions are just shortcuts for commonly used types. Other types (for example, PRUnichar, unsigned short, unsigned char) are also possible.
- Call LoadFile() to load and parse the INI configuration file.
- Use the following functions to access the file’s data:
- Call SaveFile() to save the INI configuration file (if necessary)
Interface | Case-sensitive | Typedef |
---|---|---|
char | No | CSimpleIniA |
char | Yes | CSimpleIniCaseA |
wchar_t | No | CSimpleIniW |
wchar_t | Yes | CSimpleIniCaseW |
GetAllSections | Return all section names |
---|---|
GetAllKeys | Return all key names for a section |
GetSection | Return all key names and values in a section |
GetSectionSize | Return the number of keys in a section |
GetValue | Return a value for a section & key |
SetValue | Add or update a value for a section & key |
Notes
- The collation (sorting) order used for sections and keys returned from iterators is NOT DEFINED. If collation order of the text is important, you should do it yourself by either supplying a replacement SI_STRCMP class or by sorting the strings external to this library.
- Linux/Unix systems must also compile and link ConvertUTF.c.
- To load a UTF-8 file on Windows and expose it with SI_CHAR == char, you need to define SI_USING_WIN32_CHAR_FOR_UTF8.
Download
The current version of SimpleIni is 1.5. The home page is http://code.jellycan.com/SimpleIni/.
Example Program
This program loads an INI file and dumps out all of the data from it.
#include "SimpleIni.h" int main(int argc, char * argv[]) { setlocale(LC_CTYPE, ""); if (argc < 2) { printf( "Usage: %s iniFile [useMBCS]n" " Pass 1 for useMBCS to use system locale file encodingn", argv[0]); return 1; } bool bIsUtf8 = (argc < 3) ? true : *argv[2] != '1'; const char * pDebug; printf("Dumping file using char version:n"); CSimpleIniA ini; if (0 != ini.LoadFile(argv[1], bIsUtf8)) { printf("Failed to open: %sn", argv[1]); exit(1); } CSimpleIniA::TNames sections; ini.GetAllSections(sections); CSimpleIniA::TNames::const_iterator j = sections.begin(); for ( ; j != sections.end(); ++j ) { printf("n"); if (*j[0]) { printf("[%s]n", pDebug = *j); } const CSimpleIniA::TKeyVal * pSection = ini.GetSection(*j); if (pSection) { CSimpleIniA::TKeyVal::const_iterator i = pSection->begin(); for ( ;i != pSection->end(); ++i) { printf("%s=%sn", pDebug = i->first, i->second); } } } printf("nQuerying section: [standard]n"); CSimpleIniA::TNames keys; ini.GetAllKeys("standard", keys); CSimpleIniA::TNames::const_iterator k = keys.begin(); for ( ; k != keys.end(); ++k ) { printf("Key: %sn", pDebug = *k); } pDebug = ini.GetValue("standard", "foo", 0); printf("nValue of standard::foo is '%s'n", pDebug ? pDebug : "(null)"); ini.SetValue("standard", "foo", "wibble"); pDebug = ini.GetValue("standard", "foo", 0); printf("Value of standard::foo is now '%s'n", pDebug ? pDebug : "(null)"); FILE * fp = fopen("testsi-char.ini", "wb"); if (fp) { ini.SaveFile( fp, "; testsi.cpp test output (char)" SI_NEWLINE ); fclose(fp); } return 0; }
Disclaimer
This code is released as public domain. You can do with it whatever you like: use it, modify it, distribute it, sell it, delete it, or send it to your mother-in-law. I make no promises or guarantees that this code will work correctly or at all. Use it completely at your own risk.