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

VC++ 資料型別轉換大全:CString、BSTR、LPCTSTR、TCHAR 互轉完整指南

     編輯:VC 教學

前言:MFC/ATL/COM 開發中最頭痛的型別轉換

CString、BSTR、LPCTSTR、TCHAR、char*、wchar_t*……VC++ 開發者每天都在與它們纏鬥。本文系統整理最常用、最易錯的轉換場景與正確寫法。

一、CString 建構與基本轉換

// 從字面常數建構 (自動偵測 ANSI/Unicode)
CString s1 = _T("char string");
CString s2 = L"wide char string";

// 預先配置緩衝區
CString s3(_T(' '), 100);  // 100 個空白字元

// 直接傳給 LPCTSTR 參數函數 (隱含轉換運算子)
SetWindowText(hWnd, s1);           // 正確
SetWindowText(hWnd, (LPCTSTR)s1);  // 等效顯式轉換

二、從字串表載入

// 方法 1:建構函數 (資源 ID 需轉型)
CString s4((LPCTSTR)IDS_MYSTRING);

// 方法 2:LoadString
CString s5;
s5.LoadString(IDS_MYSTRING);

// 方法 3:Format 從字串表讀取格式化字串
CString s6;
s6.Format(IDS_FORMAT_STRING, _T("bob"), 123);

三、取得可修改緩衝區指標:正確 vs 錯誤

錯誤寫法 (破壞封裝,未來版本會崩潰):

LVITEM item = {0};
item.pszText = (LPTSTR)(LPCTSTR)str;  // 錯誤!移除 const

正確寫法 (GetBuffer/ReleaseBuffer 配對):

LVITEM item = {0};
item.pszText = str.GetBuffer(0);  // 取得可寫指標,長度至少目前字串長
// ... 填充 item ...
ListView_SetItem(&item);
str.ReleaseBuffer();  // 歸還控制權,更新 CString 內部長度
  • GetBuffer(n):確保緩衝區至少 n 字元,傳 0 表示不擴充。
  • 呼叫 GetBuffer 後必須呼叫 ReleaseBuffer,否則長度不同步。
  • 切勿將 CString 轉為 LPTSTR,僅能轉 LPCTSTR。

四、CString ↔ BSTR (COM/OLE 互操作)

CString s = _T("Bob!");
BSTR bs1 = NULL, bs2 = NULL;

// 方法 1:AllocSysString (呼叫者負責 SysFreeString)
bs1 = s.AllocSysString();
::SysFreeString(bs1);

// 方法 2:SetSysString (可重複使用現有 BSTR)
s.SetSysString(&bs2);
::SysFreeString(bs2);

五、ANSI/Unicode 互轉 (TCHAR 模式切換)

// Unicode 專案中:CString → char* (需 ATL 轉換巨集)
#include 
USES_CONVERSION;
CString wstr = _T("Unicode 字串");
char* ansi = W2A(wstr);  // 分配在堆疊,函數返回失效

// 反向:char* → CString
char* ansiStr = "ANSI string";
CString wstr2 = A2W(ansiStr);

注意:W2A/A2W 回傳指標指向堆疊緩衝區,**不可跨函數儲存**,需立即複製到 CString 或 std::string。

六、數值與字串互轉

// 數值 → 字串
CString str;
str.Format(_T("%d"), 123);
str.Format(_T("%.2f"), 3.14159);

// 字串 → 數值
int n = _ttoi(_T("123"));
double d = _ttof(_T("3.14"));
long l = _ttol(_T("1234567890"));

七、常見陷阱總結表

場景錯誤寫法正確寫法
傳給 LPCTSTR(LPTSTR)(LPCTSTR)strstr / (LPCTSTR)str
取得可寫緩衝區(LPTSTR)(LPCTSTR)strstr.GetBuffer(n) / ReleaseBuffer()
CString → BSTR(BSTR)(LPCTSTR)strstr.AllocSysString() / SetSysString()
W2A 結果儲存char* p = W2A(str); 保存 pCString s = W2A(str); 保存 s
Format 緩衝區過小str.GetBuffer(10); str.Format(...超過10字元...)str.GetBuffer(預估長度); 或直接 str.Format(...)

結語

型別轉換看似瑣碎,實則關係專案穩定性與可維護性。遵循「隱含轉換只用於 LPCTSTR 讀取、寫入必須 GetBuffer/ReleaseBuffer、COM 互操作用 AllocSysString/SetSysString、跨編碼用 ATL 轉換巨集並立即複製」原則,即可避開 99% 的坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved