首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 讀取 INI 設定檔陷阱:CString::GetBuffer 必須搭配 ReleaseBuffer

     編輯:VC 教學

問題現象


CString strValue;
::GetPrivateProfileString(_T("Section"), _T("Key"), _T(""),
    strValue.GetBuffer(MAX_PATH), MAX_PATH, _T(".\\Config.ini"));
// strValue 此時長度為 0,內容為空!

根本原因

CString::GetBuffer(n) 回傳內部緩衝區指標並鎖定內容長度為 n,但 CString 物件本身的長度(GetLength())仍為 0。Windows API 寫入緩衝區後,CString 不知道資料已更新,導致後續操作(賦值、比較、operator LPCTSTR())讀到空字串。

正確做法


CString strValue;
LPTSTR pBuf = strValue.GetBuffer(MAX_PATH);
::GetPrivateProfileString(_T("Section"), _T("Key"), _T(""),
    pBuf, MAX_PATH, _T(".\\Config.ini"));
strValue.ReleaseBuffer(); // 關鍵:通知 CString 更新長度
// 現在 strValue 正常可用

封裝成工具函式


BOOL ReadIniString(LPCTSTR section, LPCTSTR key, LPCTSTR def,
                   CString& outStr, LPCTSTR iniPath)
{
    const int BUFSIZE = 1024;
    LPTSTR buf = outStr.GetBuffer(BUFSIZE);
    DWORD len = GetPrivateProfileString(section, key, def, buf, BUFSIZE, iniPath);
    outStr.ReleaseBuffer();
    return (len > 0);
}

// 使用
CString userName;
ReadIniString(_T("Custom"), _T("UserName"), _T(""), userName, _T(".\\Config.ini"));

同樣適用於其他需要緩衝區的 API

  • GetWindowsDirectory, GetSystemDirectory, GetModuleFileName
  • FormatMessage (配合 FORMAT_MESSAGE_FROM_SYSTEM)
  • 任何簽名為 LPTSTR lpBuffer, DWORD nSize 的輸出字串 API

記憶體管理提醒

  • GetBuffer 可選參數指定最小長度;若原配置不足會自動重新配置。
  • ReleaseBuffer 可選參數指定實際長度(-1 表以 null 結尾計算)。
  • 嚴禁在 GetBuffer/ReleaseBuffer 之間對同一 CString 進行其他操作(如賦值、連接),否則行為未定義。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved