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

VC 字符串類型轉換大全:CString、std::string、char*、int、BSTR 互轉最佳實踐

     編輯:關於C語言

VC 字符串類型生態

類型屬性典型用途
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

核心轉換矩陣

1. CString ↔ std::string


// 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,邊界轉換

2. CString ↔ char* / wchar_t*


// 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); // 格式化賦值

3. std::string ↔ char*


// 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)

4. CString / std::string ↔ int (數值轉換)


// 數值 → 字符串
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); // 進制控制

5. BSTR ↔ 其他 (COM 邊界)


// 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();             // 獲取副本 (需釋放)

ATL 轉換宏速查 (atlconv.h)

宏轉換方向說明
CT2ACString/LPCTSTR → const char*Unicode→ANSI (用 CP_ACP)
CT2WCString/LPCTSTR → const wchar_t*到寬字符
CA2Tconst char* → CString/LPCTSTRANSI→當前字符集
CW2Tconst wchar_t* → CString/LPCTSTR寬字符→當前字符集
COLE2TBSTR/OLESTR → LPCTSTRCOM 字符串轉換
CT2CACString → const char* (顯式 ANSI)同上
CT2CWCString → const wchar_t*同上

⚠️ 宏在函數內部使用,會在棧上分配緩衝區,**不可跨函數返回指針**。

避坑指南

  • ❌ c_str() 返回 const char* 強轉 char* 修改 → 未定義行為。需 strcpy 到可寫緩衝區。
  • ❌ GetBuffer() 未調用 ReleaseBuffer() → 長度不同步、內存洩漏/破壞。
  • ❌ BSTR 未 SysFreeString → COM 內存洩漏。用 _bstr_t/CComBSTR RAII 管理。
  • ❌ Unicode 構建下直接 CString = char* → 可能亂碼。用 CA2T 顯式轉換。
  • ❌ std::string 存儲二進制數據含 \0 → c_str() 截斷。用 data() + size()。

最佳實踐原則

  1. 內部統一:MFC 項目用 CString,標準 C++ 用 std::string/wstring,避免混用。
  2. 邊界轉換:API 調用處用 ATL 宏/構造函數一次性轉換,不持有中間指針。
  3. RAII 管理:BSTR 用 _bstr_t/CComBSTR,char* 用 std::unique_ptr/string。
  4. Unicode 優先:新項目強制 Unicode 字符集,減少轉換痛苦。

總結

VC 字符串轉換核心在於所有權傳遞、編碼轉換 (Unicode/ANSI)、生命週期管理。掌握 CString::Format/GetBuffer/ReleaseBuffer、std::to_string/stoi、ATL 轉換宏 (CT2A/CA2T)、BSTR 的 AllocSysString/SysFreeString/_bstr_t,構建類型安全的轉換輔助函數,將轉換邏輯封裝在邊界層,業務代碼保持類型純粹。

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