Inifile
A modern C++ header-only ini parser (现代C++仅头文件的ini解析器)
Install / Use
/learn @abin-z/InifileREADME
🌟 Lightweight INI File Parsing Library
🌍 Languages/语言: English | 简体中文
📌 Project Overview
This is a lightweight, cross-platform, efficient and header-only INI configuration parsing library designed for C++ projects. It provides a concise, intuitive and elegant API, supports parsing, modifying and writing INI configuration information from files, std::istream or std::string, and has line-level comment retention function to ensure that the original comments are not lost, making configuration management easier and more efficient.
⭐ Don't forget to put a star if you like the project!
🎯 Design Philosophy
There are countless INI parsing libraries, and each library even has its own reason for existence. Our design philosophy is:
- Ultimate simplicity, out-of-the-box: Header-only, zero dependencies, only C++11, easy to integrate any project.
- Focus on experience, close to the practical: support for annotation retention, automatic type conversion, custom parsing, focus on improving the developer's daily experience.
- Cross-platform, Maintainable, Reliable: Compatible with mainstream platforms, combined with unit testing and memory checking to ensure long-term stable operation.
If you are looking for a simple, functional, elegant, stable modern C++ solution, then this library is for you. If you know how to use std::map, you are ready.
🚀 Features
- Lightweight & Dependency-Free: Only relies on the C++11 standard library, no additional dependencies required.
- Easy Integration: Header-only design, out of the box, simple enough.
- Intuitive API: Provides a clear and user-friendly interface to simplify INI file operations.
- Cross-platform: Supports Linux, Windows, MacOS and other systems, as well as mainstream compilers.
- Multiple Data Sources: Supports parsing INI data from files,
std::stringorstd::istream, and writing to them. - Automatic Type Conversion: Supports multiple data types and can automatically handle type conversion (elegant API interface).
- Support comment function: Support ini line comments (
;or#), you can add line comments for[section]andkey=value(does not support end-of-line comments). - Custom type conversion: You can customize type conversion, inifile will automatically convert according to the definition you wrote (reduce duplication)
- Support case insensitivity: Provides optional case insensitivity (for
sectionandkey) - Fully tested and memory-safe: Functionality has been verified with the Catch2 unit testing framework and memory management is leak-free with Valgrind.
Ideal for C++ projects that require parsing, editing, and storing INI configuration files. The following is the basic ini format:
; comment
[section]
key = value
Note: The library uses
std::stringto encapsulate filed values internally, which is very compatible withUTF-8encoding, but other encoding specifics may be different.
📦 Installation & Usage
inifile is a Header-only C++ library and can be used in three ways:
Method 1: Copy the header directly (quick)
-
Copy the
inifile.hheader file to your project folder. -
In your source code:
#include "inifile.h"
Method 2: Using FetchContent
-
In your
CMakeLists.txt:include(FetchContent) FetchContent_Declare( inifile GIT_REPOSITORY https://github.com/abin-z/inifile.git GIT_TAG v1.0.0 ) FetchContent_MakeAvailable(inifile) # ============== Link directly ============== add_executable(app src/main.cpp) target_link_libraries(app PRIVATE inifile::inifile)💡 It is recommended to use a fixed version tag (e.g.
GIT_TAG v1.0.0) in production to ensure reproducible builds. -
In your source code:
#include <inifile/inifile.h>
Method 3: As a submodule / source integration (add_subdirectory)
-
Add
inifileas a submodule:git submodule add https://github.com/abin-z/inifile.git 3rd/inifile -
In your main
CMakeLists.txt:add_subdirectory(3rd/inifile) # Path to the submodule target_link_libraries(<your_target> PRIVATE inifile::inifile) -
In your source code:
#include <inifile/inifile.h>
Method 4: Install and use find_package (recommended for release / multi-project usage)
-
Build and install the library:
git clone --recurse-submodules https://github.com/abin-z/inifile.git cd inifile cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/your/install/path cmake --build build --config Release cmake --install build --config ReleaseWindows example:
cmake -S . -B build -A x64 -DCMAKE_INSTALL_PREFIX="C:/libs/inifile" cmake --build build --config Release cmake --install build --config Release -
In your project:
set(inifile_DIR "/your/install/path/lib/cmake/inifile") find_package(inifile REQUIRED) add_executable(app src/main.cpp) target_link_libraries(app PRIVATE inifile::inifile) -
In your source code:
#include <inifile/inifile.h>
🛠️ Examples
Below are some simple usage examples. For more details, refer to the./examples/ folder.
Creating and Saving an INI File
#include "inifile.h"
int main()
{
constexpr char path[] = "path/to/ini/file";
ini::inifile inif;
inif["section"]["key0"] = true;
inif["section"]["key1"] = 3.14159;
inif["section"]["key2"] = "value";
// Save the ini file, returns whether the save was successful or not.
bool isok = inif.save(path);
}
Reading an INI File
#include "inifile.h"
int main()
{
constexpr char path[] = "path/to/ini/file";
ini::inifile inif;
// Load the ini file, return whether the loading was successful or not.
bool isok = inif.load(path);
bool b = inif["section"]["key0"];
double d = inif["section"]["key1"];
std::string s = inif["section"]["key2"];
// Explicit type conversion via as function
bool bb = inif["section"]["key0"].as<bool>();
double dd = inif["section"]["key1"].as<double>();
std::string ss = inif["section"]["key2"].as<std::string>();
bool bbb;
double ddd;
std::string sss;
inif["section"]["key0"].as_to(bbb); // Explicit type conversion
inif["section"]["key1"].as_to(ddd); // Explicit type conversion
inif["section"]["key2"].as_to(sss); // Explicit type conversion
}
Reading/Writing INI Data from std::istream or std::ostream
#include "inifile.h"
int main()
{
// Create istream object "is" ...
ini::inifile inif;
inif.read(is);
}
#include "inifile.h"
int main()
{
// Create ostream object "os" ...
ini::inifile inif;
inif.write(os);
}
Reading/Writing INI Data from std::string
#include "inifile.h"
int main()
{
// Create string object "s" ...
ini::inifile inif;
inif.from_string(s);
}
#include "inifile.h"
int main()
{
ini::inifile inif;
inif["section"]["key"] = "value";
std::string s = inif.to_string();
}
Set value
Explanation: If the section or key does not exist, The operator[] and set functions will directly insert the section key, and if the section key exists, update the field value.
#include "inifile.h"
int main()
{
ini::inifile inif;
/// Setting a single value
inif["section"]["key1"] = "value";
inif["section"]["key2"].set("hello");
inif.set("section", "key3", true);
inif["section"].set("key4", 3.14159);
/// Setting multiple values for the same section, supporting different types
inif["section2"].set({{"bool", false},
{"int", 123},
{"double", 999.888},
{"string", "ABC"},
{"char", 'm'}});
}
Get value
Explanation: There are two things to keep in mind when getting values.
- It is important to know whether a given section key exists or not, and different calling functions will have different strategies for handling this;
- Use
operator[]to return reference. If the given section or key does not exist, will insert an empty field value and set the field to an empty string (Behavior similar tostd::map's[]). - Use the
get()function to return the value. If the given section or key does not exist, field will not be inserted, but a default empty field value (default value can be specified) will be returned. - Use the
at()function to return a reference, and if the given section or key does not exist, **th
- Use
