| 函式 | 適用場景 | 備註 |
_ttoi(str) | 十進制 int | ANSI→atoi,Unicode→_wtoi,自適應 |
_tcstol(str, &end, base) | 長整數,支援 2~36 進制 | 可檢測轉換錯誤 (檢查 end) |
_tcstoul(str, &end, base) | 無號長整數 | 同上,回傳 unsigned long |
CString hex = _T("FAB");
CString dec = _T("4011");
ASSERT(_tcstoul(hex, NULL, 16) == _ttoi(dec)); // 4011
CString ↔ char* / TCHAR* 核心機制
建構 CString (字串 → CString)
char *p = "This is a test";
TCHAR *tp = _T("Unicode aware");
CString s1 = p; // ANSI 建構
CString s2 = _T("literal"); // 字面常數
CString s3(tp); // 指標建構
CString s4 = tp; // 指標賦值 (複製內容)
關鍵:永遠複製內容,後續修改原指標不影響 CString。
CString → 唯讀指標 (LPCTSTR)
CString s(_T("GrayCat"));
LPCTSTR p = s; // 隱式轉換運算子 LPCTSTR()
const TCHAR* p2 = s; // 等價
- 回傳內部緩衝區指標,**不可修改內容**
- 指標生命週期 ≤
CString 物件生命週期
- 若
CString 重新配置記憶體 (擴容、修改),指標失效
CString → 可寫緩衝區 (GetBuffer/ReleaseBuffer)
CString s(_T("File.ext"));
LPTSTR p = s.GetBuffer(); // 取得可寫指標,長度不變
LPTSTR dot = _tcschr(p, _T('.'));
if (dot) *dot = _T('\0'); // 截斷副檔名
s.ReleaseBuffer(); // 必須配對,更新長度
擴容緩衝區
LPTSTR p = s.GetBuffer(1024); // 確保至少 1024 字元空間
// 大量填充...
s.ReleaseBuffer(); // 實際長度自動計算 (或傳入新長度)
嚴禁區:GetBuffer/ReleaseBuffer 間操作 CString
LPTSTR p = s.GetBuffer();
int n = s.GetLength(); // ❌ 錯誤!長度未更新,結果不可預期
s.TrimRight(); // ❌ 錯誤!可能觸發重新配置,p 失效
s.ReleaseBuffer(); // 之後才能正常操作
CString 格式化與數值轉字串
int nPort = 2589;
char ip[32] = "192.168.1.1";
CString str;
str.Format(_T("%d:%s"), nPort, ip); // "2589:192.168.1.1"
// 亦可用 AppendFormat 追加
str.AppendFormat(_T(" [%d]"), nPort);
CString → TCHAR* (GetBuffer 簡易版)
CString cstr(_T("hello"));
TCHAR *pstr = cstr.GetBuffer(); // 取得可寫指標
// 使用 pstr...
cstr.ReleaseBuffer();
Unicode/ANSI 可移植宏封裝
/* mr.h */
#pragma once
#ifdef UNICODE
#define _mrstrncpy wcsncpy
#define _mrstrcpy wcscpy
#define _mrstrlen wcslen
#define _mrstrcat wcscat
#define _mrstrcmp wcscmp
#else
#define _mrstrncpy strncpy
#define _mrstrcpy strcpy
#define _mrstrlen strlen
#define _mrstrcat strcat
#define _mrstrcmp strcmp
#endif
常見陷阱總結表
| 操作 | 錯誤寫法 | 正確寫法 |
| 字串連接 | CString s = "A" + "B"; | CString s = CString("A") + "B"; |
| 修改內部緩衝 | LPCTSTR p = s; p[0] = 'X'; | LPTSTR p = s.GetBuffer(); p[0]='X'; s.ReleaseBuffer(); |
| GetBuffer 間呼叫方法 | 見上文嚴禁區 | ReleaseBuffer 後再操作 |
| Format 緩衝區溢位 | str.Format(_T("%s"), huge_str); | 預估長度或用 CString::FormatV + vsnprintf 安全版 |
| 執行緒共享 | 多執行緒直接讀寫同一 CString | 加鎖或用 CStringT + 獨佔鎖策略 |
總結
- 數值轉換:
_ttoi/_tcstol/Format
- 只讀指標:隱式
LPCTSTR 轉換
- 可寫緩衝:
GetBuffer()/ReleaseBuffer() 配對,**中間不可觸碰 CString**
- Unicode 可移植:全程
_T()/TEXT()、TCHAR、_tcscpy 等通用映射
- 現代專案:考慮
std::string/std::wstring + std::format (C++20) 替代 MFC 依賴
- 上一篇文章: C 語言表達式隱式類型轉換規則與經典陷阱深度解析
- 下一篇文章: 各類排序算法的 C++ 實現與效能比較分析
Copyright ©
程式碼之家 All Rights Reserved