| 類型 | 屬性 | 典型用途 |
|---|---|---|
CString (MFC/ATL) | 引用計數、自動內存管理、Unicode/ANSI 自適應 | MFC/ATL 項目首選 |
std::string (STL) | 標準庫、跨平台、無引用計數 (C++11 起 SSO) | 標準 C++、非 MFC 代碼 |
char* / wchar_t* | C 風格、手動內存、API 邊界 | C API 交互、舊代碼 |
int / 數值類型 | 數值 | 計算、存儲 |
BSTR (COM) | 長度前綴、Unicode、SysAllocString 管理 | COM/自動化/ActiveX |
// CString → std::string (Unicode 構建下需轉碼)
std::string strStd = CT2A(cstr.GetString()); // ATL 轉換宏,需 #include
// std::string → CString
CString cstr = CA2T(strStd.c_str()); // 或 CString(strStd.c_str()) 在 MBCS 下
// 現代 C++ (C++11) 通用輔助
#include
#include // C++17 棄用,但仍可用
// Unicode 構建下推薦:保持內部用 CString/std::wstring,邊界轉換
// CString → const char* (只讀)
LPCSTR psz = cstr.GetString(); // 或 (LPCTSTR)cstr
// 注意:指針生命週期綁定 CString 對象,不可長期持有
// CString → 可修改緩衝區
LPTSTR pBuf = cstr.GetBuffer(nMinLen); // 獲取寫入指針
// ... 修改 pBuf ...
cstr.ReleaseBuffer(); // 必須調用!更新長度
// char* → CString
CString cstr = psz; // 構造/賦值自動複製
CString cstr2; cstr2.Format(_T("%s"), psz); // 格式化賦值
// string → const char*
const char* psz = str.c_str(); // 保證以 \0 結尾
const char* psz2 = str.data(); // C++11 起也保證 \0
// char* → string
std::string str(psz); // 構造複製
str.assign(psz, len); // 指定長度 (含嵌入\0)
// 數值 → 字符串
CString cstr; cstr.Format(_T("%d"), 123); // MFC 推薦
std::string str = std::to_string(123); // C++11 標準
char buf[32]; sprintf_s(buf, "%d", 123); // C 風格
// 字符串 → 數值
int n1 = _ttoi(cstr); // MFC/ATL (支持 Unicode)
int n2 = atoi(str.c_str()); // C 標準 (僅 ANSI)
int n3 = std::stoi(str); // C++11 (拋出異常)
long n4 = _tcstol(cstr, NULL, 10); // 進制控制
// BSTR → CString (ATL/MFC)
CString cstr = bstr; // CString 有 BSTR 構造/賦值運算符
// CString → BSTR (需釋放!)
BSTR bstr = cstr.AllocSysString(); // SysAllocString 複製
// 使用完畢:SysFreeString(bstr);
// BSTR → std::string (需轉碼)
std::string str = CW2A(bstr); // ATL 宏
// char* → BSTR
BSTR bstr = SysAllocStringByteLen(psz, len); // ANSI 字節
BSTR bstr = SysAllocString(L"Unicode"); // 寬字符
// 或用 _bstr_t 智能指針 (自動釋放)
_bstr_t bstrSmart = "text"; // 自動轉 BSTR
BSTR bstrRaw = bstrSmart; // 獲取裸指針 (不轉移所有權)
bstrSmart.copy(); // 獲取副本 (需釋放)
atlconv.h)| 宏 | 轉換方向 | 說明 |
|---|---|---|
CT2A | CString/LPCTSTR → const char* | Unicode→ANSI (用 CP_ACP) |
CT2W | CString/LPCTSTR → const wchar_t* | 到寬字符 |
CA2T | const char* → CString/LPCTSTR | ANSI→當前字符集 |
CW2T | const wchar_t* → CString/LPCTSTR | 寬字符→當前字符集 |
COLE2T | BSTR/OLESTR → LPCTSTR | COM 字符串轉換 |
CT2CA | CString → const char* (顯式 ANSI) | 同上 |
CT2CW | CString → const wchar_t* | 同上 |
⚠️ 宏在函數內部使用,會在棧上分配緩衝區,**不可跨函數返回指針**。
c_str() 返回 const char* 強轉 char* 修改 → 未定義行為。需 strcpy 到可寫緩衝區。GetBuffer() 未調用 ReleaseBuffer() → 長度不同步、內存洩漏/破壞。BSTR 未 SysFreeString → COM 內存洩漏。用 _bstr_t/CComBSTR RAII 管理。CString = char* → 可能亂碼。用 CA2T 顯式轉換。std::string 存儲二進制數據含 \0 → c_str() 截斷。用 data() + size()。CString,標準 C++ 用 std::string/wstring,避免混用。BSTR 用 _bstr_t/CComBSTR,char* 用 std::unique_ptr/string。VC 字符串轉換核心在於所有權傳遞、編碼轉換 (Unicode/ANSI)、生命週期管理。掌握 CString::Format/GetBuffer/ReleaseBuffer、std::to_string/stoi、ATL 轉換宏 (CT2A/CA2T)、BSTR 的 AllocSysString/SysFreeString/_bstr_t,構建類型安全的轉換輔助函數,將轉換邏輯封裝在邊界層,業務代碼保持類型純粹。