SkillAgentSearch skills...

Inifile

A modern C++ header-only ini parser (现代C++仅头文件的ini解析器)

Install / Use

/learn @abin-z/Inifile

README

🌟 Lightweight INI File Parsing Library

iniparser headeronly moderncpp cpp licenseMIT version ci ci

🌍 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::string or std::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] and key=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 section and key)
  • 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::string to encapsulate filed values internally, which is very compatible with UTF-8 encoding, 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)

  1. Copy the inifile.h header file to your project folder.

  2. In your source code:

    #include "inifile.h"
    

Method 2: Using FetchContent

  1. 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.

  2. In your source code:

    #include <inifile/inifile.h>
    

Method 3: As a submodule / source integration (add_subdirectory)

<details> <summary>Show details</summary>
  1. Add inifile as a submodule:

    git submodule add https://github.com/abin-z/inifile.git 3rd/inifile
    
  2. In your main CMakeLists.txt:

    add_subdirectory(3rd/inifile)                 # Path to the submodule
    target_link_libraries(<your_target> PRIVATE inifile::inifile)
    
  3. In your source code:

    #include <inifile/inifile.h>
    
</details>

Method 4: Install and use find_package (recommended for release / multi-project usage)

<details> <summary>Show details</summary>
  1. 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 Release
    

    Windows example:

    cmake -S . -B build -A x64 -DCMAKE_INSTALL_PREFIX="C:/libs/inifile"
    cmake --build build --config Release
    cmake --install build --config Release
    
  2. 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)
    
  3. In your source code:

    #include <inifile/inifile.h>
    
</details>

🛠️ 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 to std::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
View on GitHub
GitHub Stars21
CategoryDevelopment
Updated4d ago
Forks2

Languages

C++

Security Score

95/100

Audited on Apr 6, 2026

No findings