C++如何解析Ini配置文件

GetPrivateProfileString在Windows下简单但有硬伤:不支持UTF-8路径与编码、无法读空值、跳过含注释行、ANSI处理致中文乱码;推荐跨平台inih库,轻量单头、支持注释与UTF-8原始字节、需注意回调拷贝、重复key处理及转义规则。

c++如何解析ini配置文件

Windows平台用GetPrivateProfileString最简单但有硬伤

如果你只在Windows下跑,且Ini文件结构非常简单(无节嵌套、无转义、路径固定),GetPrivateProfileString确实能一行读值:

char buf[256];<br>GetPrivateProfileStringA("database", "host", "localhost", buf, sizeof(buf), "config.ini");

但它不支持UTF-8路径、无法读取空值、遇到注释行(;#开头)会直接跳过整行——哪怕注释在值后面,比如port=3306 ; mysql port,结果buf里啥也得不到。

更麻烦的是它把所有字符串当ANSI处理,若Ini文件是UTF-8编码(现在几乎默认如此),中文直接变乱码,且函数本身不报错,你得靠肉眼判断输出是否异常。

跨平台方案推荐inih库:轻量、头文件即用、不依赖STL

inih(INI Not Invented Here)是C写的单头文件解析器,C++项目里直接#include "ini.h"就能用,没有编译依赖。它用回调机制逐行解析,天然支持;#行内注释,且对BOM和UTF-8编码的value字段不做转换——你拿到的就是原始字节,后续用std::stringstd::u8string接住即可。

实操要点:

立即学习“C++免费学习笔记(深入)”;

  • 定义回调函数时,sectionname参数是const char*,指向内存中连续缓冲区,不要存指针,要拷贝内容
  • 若Ini里有重复key(如两个timeout=30),回调会被触发多次,需自行决定覆盖还是收集
  • 空节名([ ])和空key名(=value)默认被忽略,如需支持,得改INI_ALLOW_NOSECTIONS宏定义
  • 解析失败时不抛异常,返回负值(如-1表示文件打开失败,-2表示内存不足),必须检查返回值

自己手写解析器要注意
的处理边界

很多人抄个正则或按行split就开干,结果在Windows路径或日志格式值上翻车。Ini规范允许值中含换行(用
转义)和反斜杠(表示字面量),但实际文件里常混用

,且不同编辑器对续行符(结尾)支持不一。

关键判断点:

  • 遇到结尾的行,下一行必须拼接到当前value末尾,且去掉下一行开头的空白——但若下一行是;#,应视为注释而非续行
  • 必须替换成单个,而
    替换成实际换行符,但 等非标准转义应原样保留,别擅自扩展
  • 双引号包裹的值(如path="C: emplog.txt")不进行反斜杠转义,这是很多手写解析器漏掉的规则

std::regex解析Ini?性能差且易匹配错节名

有人想用std::regex一次性匹配[section]key=value,但正则在C++11/14里编译慢、运行慢,且Ini语法本身不适合正则:节名可含空格([My DB Config]),key可含等号(url=http://a=b/c),value可含方括号(desc=[important])。一个看似简单的^[(.*)]$会把[section] # comment里的# comment也吞进去。

更现实的问题是,std::regex在GCC 7以下版本对Unicode支持极弱,遇到UTF-8编码的节名基本匹配失败;MSVC的std::regex又不支持PCRE的原子组,导致回溯爆炸。真要用正则,建议只做预处理(比如剔除整行注释),核心解析仍用状态机。

复杂点永远在细节:空行是否算分隔、等号前后空白要不要trim、BOM要不要跳过、大小写是否敏感——这些没明确定义的地方,才是实际项目里最耗时间调试的部分。

文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xitongjiaocheng/125724.html

为什么CSS flex-grow在存在大尺寸图片时分配空间不均?
上一篇 2026-07-13 08:52
中国电信完成高轨卫星跨模态语义通信试验:星地传输效率最高提升5.5倍
下一篇 2026-07-13 09:00

相关推荐