| 通用類型 | ANSI (未定義宏) | Unicode (定義宏) | 說明 |
TCHAR | char | wchar_t | 字符類型 |
PTSTR / LPTSTR | LPSTR | LPWSTR | 可修改字符串指針 |
PCTSTR / LPCTSTR | LPCSTR | LPCWSTR | 常量字符串指針 |
_tcslen | strlen | wcslen | 字符串長度 (字符數) |
_tcscpy | strcpy | wcscpy | 複製 |
_tcscmp | strcmp | wcscmp | 比較 |
_tprintf | printf | wprintf | 格式化輸出 |
_T("text") / TEXT("text") | "text" | L"text" | 字符串字面量 (關鍵!) |
關鍵編程實踐
1. 字符串長度:字符數 vs 字節數
TCHAR str[] = _T("中文abc");
// Unicode: wcslen=6, sizeof=14字節 (含結尾\0)
// ANSI (DBCS): _tcslen=6, strlen=8字節 (中文2字節)
int charCount = _tcslen(str); // 正確字符數
int byteSize = sizeof(str); // 數組字節數
int byteLen = _tcslen(str)*sizeof(TCHAR); // 字符串內容字節數
2. DBCS 字符串安全遍歷 (僅 ANSI/DBCS 模式需手動)
Unicode 模式下 wchar_t 固定 2 字節,直接下標訪問安全。ANSI/DBCS 下必須用 API:
CharNext(lpsz):返回下一字符指針
CharPrev(lpszStart, lpszCurrent):返回上一字符指針
IsDBCSLeadByte(b):判斷是否為雙字節首字節
// 正確遍歷 DBCS 字符串
for (LPCTSTR p = str; *p; p = CharNext(p)) {
// 處理字符 *p (可能是雙字節)
}
3. 字符集轉換
// ANSI (當前代碼頁) -> Unicode
int wlen = MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, NULL, 0);
wchar_t* wstr = new wchar_t[wlen];
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wstr, wlen);
// Unicode -> ANSI
int alen = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
char* astr = new char[alen];
WideCharToMultiByte(CP_ACP, 0, wstr, -1, astr, alen, NULL, NULL);
// 指定代碼頁 (如 UTF-8: CP_UTF8, GBK: 936, Big5: 950)
MultiByteToWideChar(CP_UTF8, 0, utf8Str, -1, wstr, wlen);
4. 文件 I/O 與 Unicode
- 文件名:
CreateFile(_T("中文.txt"), ...) (TCHAR 版本自動調用 CreateFileW)
- 文件內容:建議統一寫入 UTF-8 (帶 BOM) 或 UTF-16LE。打開文件後用
MultiByteToWideChar/WideCharToMultiByte 轉換內存表示。
5. 常見陷阱
- 字面量未加 _T():
MessageBox(NULL, "中文", ...) Unicode 編譯報錯/亂碼。必須 _T("中文") 或 L"中文"。
- sizeof 陷阱:
sizeof(TCHAR) 編譯期常量 (1或2),sizeof(str) 數組字節數,strlen(str) 僅適用 ANSI。
- API 混用:
lstrlen (TCHAR) vs strlen (char) vs wcslen (wchar_t);wsprintf (TCHAR) vs sprintf/swprintf。
- 結構體對齊:包含字符串指針的結構體在 ANSI/Unicode 下大小不同,跨模塊傳遞需固定字符集或顯式聲明。
現代建議 (C++17/20, Windows 10/11)
- 內部統一 UTF-8 (std::string/u8string):跨平台、標準庫友好、網絡/文件傳輸標準。Windows API 邊界處轉 UTF-16 (
MultiByteToWideChar(CP_UTF8...))。
- 棄用 TCHAR 模型:顯式使用
wchar_t/LPWSTR 調用 Windows API (W 版本),內部用 std::u8string/std::string (UTF-8) 或 std::u16string。
- 字面量用 u8"":
u8"中文" (UTF-8), L"中文" (UTF-16), u"中文" (UTF-16 char16_t)。
- ICU / std::text (C++26):複雜文本處理 (斷詞、排序、正規化) 用成熟庫。
總結
理解 SBCS/DBCS/MBCS/Unicode 本質、TCHAR 映射機制、系統原生 Unicode (UTF-16) 與 現代 UTF-8 內部表示 的關系,是 Windows 程序員處理文本不亂碼、不崩潰、高性能的核心功力。新項目請擁抱 UTF-8 內部 + 邊界轉 UTF-16 的最佳實踐。
- 上一篇文章: Win32 用戶態調試器原理深度解析:架構、事件循環與內核交互
- 下一篇文章: Windows NT/2000 下無需驅動程式即可執行 Ring 0 代碼的實現方法
Copyright ©
程式碼之家 All Rights Reserved