用 std::ifstream 手动解析 INI 文件最可控,但需自行处理节、键、注释和空行;Windows 用 GetPrivateProfileString 最快但仅限 ANSI 编码且非跨平台;跨平台推荐 inih 库,轻量无依赖;boost::program_options 不支持 INI,易混淆。

用 std::ifstream 手动解析 INI 文件最可控,但得自己处理节、键、注释和空行
INI 文件结构简单,但标准 C++ 没有内置支持。直接用 std::ifstream 逐行读取 + 字符串切分是最轻量、兼容性最强的做法,适合嵌入式或不想引入第三方库的场景。
- 遇到
[section]就更新当前节名,后续键值对都归属该节 - 跳过以
;或#开头的行(常见注释格式),也跳过纯空白行 - 键值对按第一个
=分割,左边 trim 空格后是键,右边 trim 后是值;等号前后无空格不是强制要求,但要容错 - 值里含等号(如
url=http://a=b/c)时,只取第一个=左右部分,这是 INI 的事实标准行为
Windows 上用 GetPrivateProfileString 最快,但仅限 Win32 平台且不支持 Unicode 路径
这是 Windows API 提供的原生 INI 解析函数,调用开销极小,适合传统桌面应用。但它本质是 ANSI 接口,路径和内容都走 char*,遇到中文路径或 UTF-8 编码的 INI 文件容易乱码或失败。
- 必须确保 INI 文件保存为 ANSI(非 UTF-8)编码,否则
GetPrivateProfileString读出来是乱码 - 路径不能含 Unicode 字符,哪怕文件在
C:\用户\config.ini也会返回空字符串 - 不支持嵌套节、数组语法、引号包裹值等扩展写法,纯正 INI 规范子集
- 示例调用:
GetPrivateProfileString("db", "host", "localhost", buffer, sizeof(buffer), "config.ini")
跨平台项目建议用 inih 库,头文件仅一个 ini.h,无编译依赖
inih(INI Not Invented Here)是 C 写的轻量解析器,C++ 可直接 #include 使用,不需链接、不占体积,GitHub 上维护活跃,被 SQLite、libuv 等项目采用。
- 只需实现一个回调函数,每读到一个键值对或节就触发一次,控制权完全在你手里
- 自动跳过注释、空行、行尾空格;支持
;和#两种注释符 - 不加载整个文件进内存,适合大配置文件;也不做任何内存分配,适合资源受限环境
- 注意:它只解析,不提供“根据节名查键”这种高级接口,你要自己建
std::map<:string std::map std::string>>结构缓存
别用 boost::program_options 解析 INI,它根本不支持 INI 格式
有人看到 Boost 有配置解析能力就默认它能读 INI,实际 boost::program_options 只支持命令行参数、环境变量和 Windows 注册表,没有 INI 解析器。强行用会导致编译失败或运行时断言崩溃。
- 错误现象:
undefined reference to `boost::program_options::parse_config_file'—— 因为这个函数根本不存在 - 混淆来源:Boost 有个独立库
boost::property_tree支持 INI,但它会把节名转成点分路径(如[db] host=127.0.0.1变成db.host),且无法区分同名键在不同节里的语义 - 更麻烦的是:
property_tree读取时会静默丢弃注释、合并重复键、忽略空节,配置可维护性差
INI 解析真正难的不是读出值,而是当多个配置源(INI + 命令行 + 环境变量)叠加时,谁覆盖谁、类型怎么转换、错误位置怎么定位——这些得你自己定规则,没通用解。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











