Windows平台用GetPrivateProfileString最直接,它是系统级Win32 API,无需第三方依赖、调用开销小;但仅限Windows、需ANSI/UTF-16编码、路径须绝对、缓冲区须预分配且检查返回值防截断,不支持嵌套节或现代语法扩展。

Windows平台用GetPrivateProfileString最直接
如果你只在Windows下开发,且配置文件是传统INI格式(如app.ini),GetPrivateProfileString是系统级支持、无需第三方依赖的最快路径。它本质是Win32 API,头文件为Windows.h,链接kernel32.lib(通常默认链接)。
常见错误是传入缓冲区大小时写成sizeof(buffer)但没初始化buffer,或忽略返回值——该函数返回实际写入字符数(不含终止符),若返回0可能表示键不存在、节不存在,或buffer太小导致截断。
- 必须确保
lpReturnedString指向至少nSize字节的可写内存,且nSize至少为1(否则行为未定义) - 若INI文件路径含中文,需用宽字符版本
GetPrivateProfileStringW,并以UTF-16 LE或系统本地编码保存文件 - 该API不支持嵌套节、注释保留、空行跳过等现代需求,纯用于简单键值读取
// 示例:读取 [Network] 下的 Port
TCHAR portStr[32] = {0};
GetPrivateProfileString(_T("Network"), _T("Port"), _T("8080"), portStr, _countof(portStr), _T("config.ini"));
int port = _ttoi(portStr);
跨平台项目优先选inih库
需要Linux/macOS兼容,又不想引入重量级依赖(如Boost.PropertyTree),inih(INI Not Invented Here)是极简C库,仅两个文件(ini.h/ini.c),header-only用法也支持。它不解析值,只回调每行的节、键、值,由你决定如何转换和存储。
容易踩的坑是误以为它自动处理类型转换——它只提供const char*原始字符串,atoi/strtol需自行调用;另外默认不忽略BOM,UTF-8带BOM的INI文件会导致首节名乱码。
立即学习“C++免费学习笔记(深入)”;
- 回调函数中
section或name可能为NULL(对应无节全局键或注释行),需判空 - 若INI中有重复键名,
inih按出现顺序多次回调,不会覆盖,逻辑需自行去重或取最后一个 - 编译时定义
INI_USE_STACK可避免malloc,适合嵌入式环境
用std::filesystem前先确认文件存在且可读
C++17起可用std::filesystem::exists和std::filesystem::is_regular_file检查INI路径,但很多人忽略权限问题:Windows上文件可能被其他进程独占打开(如记事本未关闭),Linux上则可能因umask或SELinux限制导致open()失败。此时ifstream构造后调用is_open()比直接读取更早暴露问题。
- 绝对路径建议用
std::filesystem::absolute标准化,避免../导致路径解析歧义 - 相对路径默认基于当前工作目录(不是可执行文件目录),调试时易错位,可用
GetModuleFileName(Windows)或/proc/self/exe(Linux)获取程序路径再拼接 - 读取后建议用
std::string::find_first_not_of(" ")跳过空白行和注释(以;或#开头),inih已内置此逻辑,手写解析器常漏掉
不要用std::regex解析INI结构
看似能用正则匹配[Section]、key=value,但INI实际语法比想象复杂:值中可含等号(path=C:oo=bar)、引号包裹空格(name="John Doe")、反斜杠转义(dir=C:\Program Files\)。C++标准std::regex在不同编译器(MSVC/libc++/libstdc++)对Unicode和回溯控制差异大,性能也不佳。
- 即使简单场景,
std::regex编译耗时不可忽略,INI文件每次启动都重新compile regex是典型低效操作 - 真正需要灵活语法时,应换用专用INI解析器(如
cpptoml支持TOML超集),而非硬怼正则 - 手写状态机解析50行以内即可覆盖95%的INI需求,可控性远高于正则
INI格式表面简单,但生产环境里文件编码、BOM、路径权限、键名大小写敏感性、值内特殊字符这些细节,比语法本身更消耗调试时间。


















