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

Windows 字串類型完全指南:ANSI、Unicode、TCHAR、BSTR 與 C++ 標準庫轉換詳解

     編輯:關於C語言

Windows 開發中最讓人頭疼的莫過於琳瑯滿目的字串類型:char*、wchar_t*、LPSTR、LPTSTR、BSTR、CString、std::string……本文從字符本質出發,系統梳理類型體系、命名規則、相互轉換最佳實踐。

1. 字符本質:ANSI vs Unicode

  • ANSI (MBCS):char,1 字節/字符,編碼取決於當前代碼頁(CP_ACP)。
  • Unicode (UTF-16LE):wchar_t,2 字節/字符,固定寬度。

Windows 內核原生使用 Unicode,ANSI API 實際上是內部轉換後調用 Unicode 版本,效率較低。

2. Windows 類型別名體系

基礎類型指針類型常量指針含義
CHARPSTR/LPSTRPCSTR/LPCSTRANSI 字符/字串
WCHARPWSTR/LPWSTRPCWSTR/LPCWSTRUnicode 字符/字串
TCHARPTSTR/LPTSTRPCTSTR/LPCTSTR視 UNICODE 宏切換 ANSI/Unicode

L 前綴(Long Pointer)在 32/64 位系統無實際區別,純歷史遺留。

3. 通用宏與字面量

#ifdef UNICODE
    #define __TEXT(q) L##q
    typedef WCHAR TCHAR;
#else
    #define __TEXT(q) q
    typedef CHAR TCHAR;
#endif
#define TEXT(q) __TEXT(q)

// 用法
TEXT("Hello")  // UNICODE=on → L"Hello",off → "Hello"

4. 特殊類型

  • BSTR:COM 專用,長度前綴 + 內容 + 雙空終止。前 4 字節存長度(字符數),地址指向第一個字符。適用跨語言(VB/JS/C++)傳遞。
  • std::string / std::wstring:C++ 標準庫,RAII 管理內存,推薦現代 C++ 內部使用。
  • CString (MFC/ATL):引用計數、格式化豐富、隱式轉換 LPCTSTR,MFC 專項首選。

5. 轉換策略大全

等號直接轉換(同類型別名)

CHAR* == PSTR == LPSTR
WCHAR* == PWSTR == LPWSTR
TCHAR* == PTSTR == LPTSTR

ANSI ↔ Unicode(核心轉換)

方法一:ATL/MFC 宏(簡單、栈分配,慎用於大循環)

USES_CONVERSION;
WCHAR* wsz = L"Unicode";
CHAR*  sz  = "ANSI";
printf("%s\n", W2A(wsz));   // Unicode → ANSI
wprintf(L"%s\n", A2W(sz));  // ANSI → Unicode

⚠️ 宏使用 alloca 棧分配,大循環/長字串會棧溢出。

方法二:WinAPI 標準函數(堆分配、可控、高性能)

// ANSI → Unicode
int len = MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, nullptr, 0);
WCHAR* wsz = new WCHAR[len];
MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, wsz, len);

// Unicode → ANSI
len = WideCharToMultiByte(CP_ACP, 0, wszUnicode, -1, nullptr, 0, nullptr, nullptr);
CHAR* sz = new CHAR[len];
WideCharToMultiByte(CP_ACP, 0, wszUnicode, -1, sz, len, nullptr, nullptr);

參數詳解:CP_ACP 當前系統代碼頁,-1 表示以 \0 結尾自動計算長度。

BSTR ↔ ANSI/Unicode

// ANSI → BSTR
BSTR bstr = _bstr_t("ANSI string"); // _bstr_t 管理引用計數

// BSTR → ANSI
_bstr_t wrapper(bstr);
CHAR* sz = wrapper; // 隱式轉換操作符

CString ↔ std::string

CString cstr = _T("Hello");
std::string s1 = CT2A(cstr);        // MFC/ATL 宏
std::wstring s2 = CT2W(cstr);

// 反向
CString cstr2 = CA2T(stdStr.c_str());
CString cstr3 = CW2T(stdWStr.c_str());

6. 最佳實踐建議

  1. 內部統一用 Unicode:定義 UNICODE/_UNICODE,所有內部 API 用 WCHAR/std::wstring,邊界處轉換。
  2. 優先用標準庫:std::string/std::wstring 配合 MultiByteToWideChar/WideCharToMultiByte,避免宏陷阱。
  3. COM 介面必用 BSTR:_bstr_t/CComBSTR 管理生命週期。
  4. MFC 專項用 CString:利用其格式化、隱式轉換優勢。
  5. 切勿在循環中用 W2A/A2W:改用 API 函數並復用緩衝區。

掌握類型本質與轉換邊界,是 Windows 系統級開發的基本功。

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