Windows MFC 桌面开发函数小记(INI读写、路径获取、CString缓冲区)

发布时间:2026/9/13 11:40:37
Windows MFC 桌面开发函数小记(INI读写、路径获取、CString缓冲区) 文档说明本文档整理 MFC/Win32 桌面开发最高频、最容易踩坑三大模块INI配置文件读写、EXE路径获取、CString GetBuffer 缓冲区操作。所有内容修正网络博客错误知识点完全依据微软官方文档适配 Unicode、VS 全版本、32/64位工业级项目可直接用于检测软件、工控上位机等正式项目。一、INI 配置文件读写Win32 官方 API1.1 INI 文件标准格式严格区分节(Section)、键(Key)、值(Value)API不区分大小写[SectionName] key1value1 key2value21.2 写入 INI 文件WritePrivateProfileString函数原型BOOL WritePrivateProfileString( LPCTSTR lpAppName, // 节名 LPCTSTR lpKeyName, // 键名 LPCTSTR lpString, // 写入值 LPCTSTR lpFileName // INI完整路径 );关键权威规则重点修正网络错误lpKeyNameNULL删除整个【节】lpStringNULL删除当前【键】路径必须是完整绝对路径相对路径极易读写出错目录必须提前存在API不会自动创建文件夹只会创建文件工程标准示例Unicode 兼容、无乱码CString strName _T(张三); int nAge 25; CString strAge; strAge.Format(_T(%d), nAge); // 建议使用 EXE 运行目录不写死C/D盘路径 CString strIniPath _T(./config/system.ini); ::WritePrivateProfileString(_T(UserInfo), _T(UserName), strName, strIniPath); ::WritePrivateProfileString(_T(UserInfo), _T(Age), strAge, strIniPath);1.3 读取 INI 文件字符串 整型读取字符串 GetPrivateProfileStringDWORD GetPrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName );正确读取示例杜绝缓冲区溢出TCHAR szBuf[256] { 0 }; CString strIniPath _T(./config/system.ini); ::GetPrivateProfileString(_T(Server), _T(IP), _T(127.0.0.1), szBuf, _countof(szBuf), strIniPath); CString strServerIP szBuf;读取整型 GetPrivateProfileIntint nPort ::GetPrivateProfileInt(_T(Server), _T(Port), 8080, strIniPath);1.4 重大坑点INI API 存在系统缓存频繁读写不会实时刷新调试时修改INI不生效是正常现象中文乱码根源INI文件必须保存为ANSIUnicode 写入会乱码官方API硬编码路径带空格必须完整路径不能使用相对路径微软官方新项目不推荐INI建议JSON/注册表但工控软件仍普遍使用二、获取 EXE 运行路径GetModuleFileName2.1 函数作用获取当前 exe完整绝对路径含文件名是所有配置文件、日志、资源加载的基础。2.2 标准获取 截断目录修正错误写法网络大量旧代码存在内存越界、指针悬空问题以下为安全版本TCHAR szFullPath[MAX_PATH] { 0 }; // 获取当前EXE完整路径 ::GetModuleFileName(NULL, szFullPath, MAX_PATH); // 安全截断保留目录删除exe文件名 CString strAppPath(szFullPath); int nPos strAppPath.ReverseFind(_T(\\)); if (nPos ! -1) { strAppPath strAppPath.Left(nPos 1); } // strAppPath D:/Project/Debug/2.3 关键注意事项构造函数中禁止调用窗口未初始化完毕路径可能获取失败MAX_PATH 260超长路径需开启长路径支持Debug/Release 路径自动适配无需硬编码可直接拼接 ini、log、资源路径strAppPath _T(config.ini)三、CString GetBuffer / ReleaseBuffer这是 MFC 最容易写出内存BUG的知识点下面完全纠正错误教程。3.1 核心原理GetBuffer交出字符串内部缓冲区控制权允许外部修改内存。ReleaseBuffer收回控制权重新计算字符串真实长度。3.2 函数原型LPTSTR GetBuffer(int nMinBufLength); void ReleaseBuffer(int nNewLength -1);3.3 正确使用模板必须遵守CString strText _T(); // 1. 申请缓冲区 LPTSTR pBuf strText.GetBuffer(512); // 2. 直接写内存Windows API、串口、文件、网络接收常用 _tcscpy_s(pBuf, 512, _T(新内容)); // 3. 必须释放更新CString内部长度 strText.ReleaseBuffer(); // 4. 之后才能正常使用 strText 的所有接口 qDebug() strText;3.4 权威正误判定微软官方标准✅ 正确场景修改缓冲区内容 →必须 ReleaseBuffer调用 Win32 API 输出字符串缓冲区❌ 错误场景GetBuffer 之后不 Release→ CString 长度错乱、截断、内存状态异常GetBuffer 和 ReleaseBuffer 中间调用 CString 其他方法 → 缓冲区重分配、指针野指针只读读取缓冲区却调用 ReleaseBuffer → 多余但无害3.5 最简判断口诀写必释读不必释修改了缓冲区内容 → 必须 ReleaseBuffer()只读取、不修改 → 无需 ReleaseBuffer3.6 高危后果工业软件循环内遗漏 ReleaseBuffer → 字符串越来越乱、拼接错乱、日志异常内存状态不一致 → 偶发崩溃最难排查的随机BUGSaveFile/导出数据时内容截断四、工程实践整合可用4.1 项目统一配置文件路径函数static CString GetAppIniPath() { TCHAR szPath[MAX_PATH] { 0 }; GetModuleFileName(NULL, szPath, MAX_PATH); CString strPath(szPath); int nPos strPath.ReverseFind(_T(\\)); if (nPos ! -1) { strPath strPath.Left(nPos 1) _T(config.ini); } return strPath; }