Cross-platform C++ library providing a simple API to read and write INI-style configuration files

Overview

simpleini

Build Status

A cross-platform library that provides a simple API to read and write INI-style configuration files. It supports data files in ASCII, MBCS and Unicode. It is designed explicitly to be portable to any platform and has been tested on Windows, WinCE and Linux. Released as open-source and free using the MIT licence.

Feature Summary

  • MIT Licence allows free use in all software (including GPL and commercial)
  • multi-platform (Windows 95 to Windows 10, Windows CE, Linux, Unix)
  • loading and saving of INI-style configuration files
  • configuration files can have any newline format on all platforms
  • liberal acceptance of file format
    • key/values with no section
    • removal of whitespace around sections, keys and values
  • support for multi-line values (values with embedded newline characters)
  • optional support for multiple keys with the same name
  • optional case-insensitive sections and keys (for ASCII characters only)
  • saves files with sections and keys in the same order as they were loaded
  • preserves comments on the file, section and keys where possible
  • 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
  • should compile with no warnings in most compilers

Documentation

Full documentation of the interface is available in doxygen format.

Examples

These snippets are included with the distribution in the automatic tests as ts-snippets.cpp.

SIMPLE USAGE

	// simple demonstration

	CSimpleIniA ini;
	ini.SetUnicode();

	SI_Error rc = ini.LoadFile("example.ini");
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_OK);

	const char* pv;
	pv = ini.GetValue("section", "key", "default");
	ASSERT_STREQ(pv, "value");

	ini.SetValue("section", "key", "newvalue");

	pv = ini.GetValue("section", "key", "default");
	ASSERT_STREQ(pv, "newvalue");

LOADING DATA

	// load from a data file
	CSimpleIniA ini;
	SI_Error rc = ini.LoadFile("example.ini");
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_OK);

	// load from a string
	const std::string example = "[section]\nkey = value\n";
	CSimpleIniA ini;
	SI_Error rc = ini.LoadData(example);
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_OK);

GETTING SECTIONS AND KEYS

	// get all sections
	CSimpleIniA::TNamesDepend sections;
	ini.GetAllSections(sections);

	// get all keys in a section
	CSimpleIniA::TNamesDepend keys;
	ini.GetAllKeys("section1", keys);

GETTING VALUES

	// get the value of a key that doesn't exist
	const char* pv;
	pv = ini.GetValue("section1", "key99");
	ASSERT_EQ(pv, nullptr);

	// get the value of a key that does exist
	pv = ini.GetValue("section1", "key1");
	ASSERT_STREQ(pv, "value1");

	// get the value of a key which may have multiple 
	// values. If hasMultiple is true, then there are
	// multiple values and just one value has been returned
	bool hasMulti;
	pv = ini.GetValue("section1", "key1", nullptr, &hasMulti);
	ASSERT_STREQ(pv, "value1");
	ASSERT_EQ(hasMulti, false);

	pv = ini.GetValue("section1", "key2", nullptr, &hasMulti);
	ASSERT_STREQ(pv, "value2.1");
	ASSERT_EQ(hasMulti, true);

	// get all values of a key with multiple values
	CSimpleIniA::TNamesDepend values;
	ini.GetAllValues("section1", "key2", values);

	// sort the values into a known order, in this case we want
	// the original load order
	values.sort(CSimpleIniA::Entry::LoadOrder());

	// output all of the items
	CSimpleIniA::TNamesDepend::const_iterator it;
	for (it = values.begin(); it != values.end(); ++it) {
		printf("value = '%s'\n", it->pItem);
	}

MODIFYING DATA

	// add a new section 
	rc = ini.SetValue("section1", nullptr, nullptr);
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_INSERTED); 

	// not an error to add one that already exists
	rc = ini.SetValue("section1", nullptr, nullptr);
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_UPDATED);

	// get the value of a key that doesn't exist
	const char* pv;
	pv = ini.GetValue("section2", "key1", "default-value");
	ASSERT_STREQ(pv, "default-value");

	// adding a key (the section will be added if needed)
	rc = ini.SetValue("section2", "key1", "value1");
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_INSERTED);

	// ensure it is set to expected value
	pv = ini.GetValue("section2", "key1", nullptr);
	ASSERT_STREQ(pv, "value1");

	// change the value of a key
	rc = ini.SetValue("section2", "key1", "value2");
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_UPDATED);

	// ensure it is set to expected value
	pv = ini.GetValue("section2", "key1", nullptr);
	ASSERT_STREQ(pv, "value2");

DELETING DATA

	// deleting a key from a section. Optionally the entire
	// section may be deleted if it is now empty.
	bool done, deleteSectionIfEmpty = true;
	done = ini.Delete("section1", "key1", deleteSectionIfEmpty);
	ASSERT_EQ(done, true);
	done = ini.Delete("section1", "key1");
	ASSERT_EQ(done, false);

	// deleting an entire section and all keys in it
	done = ini.Delete("section2", nullptr);
	ASSERT_EQ(done, true);
	done = ini.Delete("section2", nullptr);
	ASSERT_EQ(done, false);

SAVING DATA

	// save the data to a string
	std::string data;
	rc = ini.Save(data);
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_OK);

	// save the data back to the file
	rc = ini.SaveFile("example2.ini");
	if (rc < 0) { /* handle error */ };
	ASSERT_EQ(rc, SI_OK);
You might also like...
A small and portable INI file library with read/write support

minIni minIni is a portable and configurable library for reading and writing ".INI" files. At just below 900 lines of commented source code, minIni tr

log4cplus is a simple to use C++ logging API providing thread-safe, flexible, and arbitrarily granular control over log management and configuration. It is modelled after the Java log4j API.

% log4cplus README Short Description log4cplus is a simple to use C++17 logging API providing thread--safe, flexible, and arbitrarily granular control

RemixDB: A read- and write-optimized concurrent KV store. Fast point and range queries. Extremely low write-amplification.

REMIX and RemixDB The REMIX data structure was introduced in paper "REMIX: Efficient Range Query for LSM-trees", FAST'21. This repository maintains a

AMD K6-2 (CXT) / K6-2+ / K6-3 / K6-3+ Write Allocate / Write Combine / Write Ordering / Frequency Multiplier Initialization driver for MS-DOS

K6INIT What is this? This is a driver for MS-DOS to replace k6dos.sys which is a bit useless and unflexible. It does not support the CXT versions of t

This is a JSON C++ library. It can write and read JSON files with ease and speed.

Json Box JSON (JavaScript Object Notation) is a lightweight data-interchange format. Json Box is a C++ library used to read and write JSON with ease a

Common files for Packet Batch. Read this for configuration guidance and more!

Packet Batch (Common) Description This is a repository for Packet Batch that includes common files for all versions of Packet Batch to use (standard,

Cross-platform, graphics API agnostic,
Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.

bgfx - Cross-platform rendering library GitHub Discussions Discord Chat What is it? Cross-platform, graphics API agnostic, "Bring Your Own Engine/Fram

Read and write rosbag on a platform without ROS installed, using MQTT for message delivery.

EasyRosBag x86_64: Test on Ubuntu18.04 arm64 : Test on Ubuntu21.04(raspberry Pi4) Introducton ROS(Robot Operation System) is too fat!!! We do not ins

Serverless SQLite database read from and write to Object Storage Service, run on FaaS platform.

serverless-sqlite Serverless SQLite database read from and write to Object Storage Service, run on FaaS platform. NOTES: This repository is still in t

Blog post on using a custom Bash builtin to parse INI config files

Writing a Bash Builtin in C to Parse INI Configs Why Not Just Parse INI Configs With Bash? Shell languages such as Bash excel at certain tasks, such a

A simple windows driver that can read and write to process memory from kernel mode

ReadWriteProcessMemoryDriver A simple windows driver that can read and write to process memory from kernel mode This was just a small project for me t

Open Source, cross platform C++ library providing integration of VulkanSceneGraph with Qt windowing

Open Source, cross platform C++ library providing integration of VulkanSceneGraph with Qt windowing. Supports Windows, Linux and macOS.

Simple .INI file parser in C, good for embedded systems

inih (INI Not Invented Here) inih (INI Not Invented Here) is a simple .INI file parser written in C. It's only a couple of pages of code, and it was d

Simple .INI file parser in C, good for embedded systems

inih (INI Not Invented Here) inih (INI Not Invented Here) is a simple .INI file parser written in C. It's only a couple of pages of code, and it was d

Stealthy way to hijack the existing game process handle within the game launcher (currently supports Steam and Battle.net). Achieve external game process read/write with minimum footprint.
Stealthy way to hijack the existing game process handle within the game launcher (currently supports Steam and Battle.net). Achieve external game process read/write with minimum footprint.

Launcher Abuser Stealthy way to hijack the existing game process handle within the game launcher (currently supports Steam and Battle.net). Achieve ex

Haxe native extension to read and write windows clipboard.

Haxe Clipboard This is a native library to read and write clipboard data from Haxe. It uses Ammer to generate bindings. Note: This is a Windows only l

This software brings you the possibility to Read and Write the internal Flash of the Nordic nRF52 series with an ESP32
This software brings you the possibility to Read and Write the internal Flash of the Nordic nRF52 series with an ESP32

ESP32 nRF52 SWD flasher This software brings you the possibility to Read and Write the internal Flash of the Nordic nRF52 series with an ESP32 using t

Ntfs-3g - NTFS-3G Safe Read/Write NTFS Driver

INTRODUCTION ============ The NTFS-3G driver is an open source, freely available read/write NTFS driver for Linux, FreeBSD, macOS, NetBSD, OpenIndia

This is a set of utilities that allow you to read, write or erase SPI flash chips using a Raspberry Pi Pico (RP2040) chip.

Pico SPI Utilities This is a set of utilities that allow you to read, write or erase SPI flash chips using a Raspberry Pi Pico (RP2040) chip. While th

Releases(v4.19)
Owner
Brodie Thiesfield
Brodie Thiesfield
C++20 single-header library for embedding INI configs

ini-config A single-header library that converts INI-formatted string literals to a key-value pair list at compile-time. Requires C++20; tested on gcc

clyne 54 Jun 21, 2022
ini file parser

Iniparser 4 I - Overview This modules offers parsing of ini files from the C level. See a complete documentation in HTML format, from this directory o

Nicolas D 818 Sep 25, 2022
CfgManipulator is a powerful tool for manipulating configuration files.

CfgManipulator is a powerful tool for manipulating configuration files

Sanya 1 Feb 3, 2022
Small configuration file parser library for C.

libConfuse Introduction Documentation Examples Build & Install Origin & References Introduction libConfuse is a configuration file parser library writ

null 412 Sep 20, 2022
Mast is setup tool for Linux Mint configuration which provides this functionalities

Mast Mint Additional Setup Tool discord what is Mast? Mast is setup tool for Linux Mint configuration which provides this functionalities

Jakub 8 Dec 25, 2021
config-loader is a static reflection framework written in C++17 from parse configuration file to native data structure.

config-loader is a static reflection framework written in C++17 from parse configuration file to native data structure.

Netcan 103 Sep 22, 2022
Lua as an advanced configuration language for wayfire

wf-lua Experiment to use Lua as an advanced configuration language for wayfire. wf-lua is meant for use-cases where writing an actual wayfire plugin s

Javier Pollak 14 Aug 3, 2022
Device configuration for Redmi K30 Ultra

The Redmi K30 Ultra (codenamed "cezanne") is a high-end smartphone from Xiaomi.

Misty 5 Apr 9, 2022
Header-only TOML config file parser and serializer for C++17 (and later!).

toml++ homepage ✨ This README is fine, but the toml++ homepage is better. ✨ Library features Header-only Supports the latest TOML release (v1.0.0), pl

Mark Gillard 892 Oct 1, 2022
A fast and easy to configure alternative to neofetch written in C and configured using Lua

lcfetch A fast and easy to configure alternative to neofetch written in C and configured using Lua (still in a very early stage)! IMPORTANT: I'm a new

Alejandro 23 Jul 29, 2022