CString

1.CString分别在MFC、WTL、ATL中都有实现,但是用法基本一样。


//using cstring
typedef CHAR *LPSTR;
typedef WCHAR *LPWSTR;
#ifdef UNICODE
 typedef LPWSTR LPTSTR;
#else
 typedef LPSTR LPTSTR;
#endif

using ATL::CStringA;
using ATL::CString;
using ATL::CStringW;
/**
ATL::CStringA cstra / LPSTR
ATL::CStringW cstrw / LPWSTR
ATL::CString cstr / LPTSTR
**/
//eg: string as function outputs

CStringA GetUinfo(LPSTR id);
CStringW GetUinfo(LPWSTR id);
CString GetUinfo(CString& id);
CStringW myString1 = _T("This is a test");
CStringA myString2 = "This is a test";
wchar_t wchar1[40] = {0};
char char2[40] = {0};
strcpy(char2, (LPCSTR)myString2);
wcscpy(wchar1, (LPCWSTR)myString1);
strcpy(myString2.GetBuffer(40), "this is copy string!");
myString2.ReleaseBuffer();
wcscpy(myString1.GetBuffer(40), _T("this is copy string!"));
myString2.ReleaseBuffer();


<think>我们正在讨论的是TCHAR和CString的相关知识。根据之前的引用内容,我们可以总结出以下几点: 1. TCHAR是一种通用的字符类型,用于支持Unicode和多字节字符集(MBCS)。在编译时,根据是否定义了_UNICODE宏,TCHAR会被定义为wchar_t(Unicode)或char(MBCS)。 2. CString是MFC中用于处理字符串的类,它封装了字符串操作,并且可以自动处理内存分配和释放。CString支持Unicode和MBCS,根据项目的字符集设置,CString内部使用TCHAR来存储字符。 接下来,我将详细介绍TCHAR和CString,包括它们的定义、转换方法以及使用示例。 ### TCHAR详解 TCHAR是为了实现代码的通用性而定义的类型。在Windows编程中,当我们希望同一份代码既可以编译为Unicode版本又可以编译为ANSI版本时,使用TCHAR。 ```c #ifdef _UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif ``` 常见的TCHAR字符串处理函数以_tcs开头,例如_tcscpy(对应strcpy或wcscpy)、_tcslen(对应strlen或wcslen)等。 ### CString详解 CString是MFC中一个功能强大的字符串类,它提供了丰富的成员函数用于字符串操作。CString对象可以自动管理内存,当CString对象超出作用域时,其析构函数会自动释放内存。 主要特点: - 支持动态内存分配,字符串长度可动态变化 - 提供丰富的成员函数(如GetLength、TrimLeft、TrimRight、Format等) - 支持运算符重载(如=、+、+=、==、!=等) - 与基本类型的转换(如int、double转换为CString,以及反向转换) ### TCHAR与CString的转换 #### 1. CString 转 TCHAR* (LPTSTR) 有两种常用方法: **方法1:使用GetBuffer** ```cpp CString str = _T("Hello"); LPTSTR lpsz = str.GetBuffer(str.GetLength()); // 使用lpsz... str.ReleaseBuffer(); // 释放缓冲区,必须调用 ``` 注意:使用GetBuffer后必须调用ReleaseBuffer,否则可能导致CString内部状态不一致。 **方法2:分配内存并复制** ```cpp CString str = _T("Hello"); LPTSTR lpsz = new TCHAR[str.GetLength() + 1]; _tcscpy(lpsz, (LPCTSTR)str); // 使用lpsz... delete[] lpsz; // 记得释放内存 ``` #### 2. TCHAR* 转 CString 可以直接赋值: ```cpp TCHAR* szText = _T("World"); CString str = szText; // 直接赋值 ``` #### 3. CString 与 int/double 的转换 **CString转int** ```cpp CString str = _T("123"); int n = _ttoi(str); ``` **CString转double** ```cpp CString str = _T("3.14"); double d = _tstof(str); ``` **int/double转CString** ```cpp int n = 456; double d = 1.23; CString str1; str1.Format(_T("%d"), n); CString str2; str2.Format(_T("%f"), d); ``` #### 4. CString 与 std::string 的转换 **std::string 转 CString** ```cpp std::string s = "abc"; CString str(s.c_str()); // 对于多字节字符集 // 或者 CString str = CA2T(s.c_str()); // 使用ATL转换宏,需要包含<atlstr.h> ``` **CString 转 std::string** ```cpp CString str = _T("abc"); std::string s = CT2A(str.GetString()); // 使用ATL转换宏 // 或者对于多字节版本 CStringA strA(str); std::string s = strA.GetString(); ``` ### 使用示例 以下是一个综合示例,展示如何在MFC应用程序中使用CString和TCHAR: ```cpp void CMyClass::ProcessStrings() { // 创建CString CString str1 = _T("Hello"); CString str2 = _T("World"); // 字符串连接 CString str3 = str1 + _T(", ") + str2 + _T("!"); // 转换为TCHAR* LPTSTR lpsz = new TCHAR[str3.GetLength() + 1]; _tcscpy(lpsz, str3); // 使用TCHAR*进行操作 // ... // 释放内存 delete[] lpsz; // 格式化字符串 int nCount = 10; CString strMsg; strMsg.Format(_T("Count: %d"), nCount); // 显示消息 AfxMessageBox(strMsg); } ``` ### 注意事项 1. **字符集一致性**:确保项目设置(Unicode或多字节字符集)与代码中使用的字符类型一致。 2. **内存管理**:当使用`new`分配内存时,必须记得使用`delete[]`释放。 3. **GetBuffer/ReleaseBuffer**:使用`GetBuffer`获取内部缓冲区指针后,如果修改了字符串长度,必须调用`ReleaseBuffer`来更新CString内部状态。 4. **ATL转换宏**:在涉及不同字符集转换时(如Unicode到ANSI),推荐使用ATL转换宏(如CA2T、CT2A等),它们简化了转换过程并自动处理内存。 ### 相关问题 根据上述内容,生成相关问题如下: §§相关问题§§ 1. 如何在Unicode环境下正确使用CString和TCHAR? 2. CString的Format函数有哪些常用格式符? 3. 使用GetBuffer获取CString缓冲区时有哪些注意事项? 4. 如何避免在使用TCHAR指针时的内存泄漏问题? 5. 在MFC中,如何将CString与控件(如编辑框Edit Control)进行数据交换? </think>### TCHAR与CString详解 #### 一、TCHAR类型 TCHAR是Windows编程中的通用字符类型,用于支持Unicode和ANSI双模式编译: ```c #ifdef _UNICODE typedef wchar_t TCHAR; // Unicode模式 #else typedef char TCHAR; // ANSI模式 #endif ``` **核心特性**: 1. **跨平台兼容**:自动适配系统字符集(Unicode/ANSI)[^5] 2. **前缀规范**: - `_T()`宏定义文本:`_T("Hello")` - 字符串函数:`_tcscpy()`代替`strcpy()`/`wcscpy()` 3. **内存占用**: - Unicode模式:每个字符2字节 - ANSI模式:每个字符1字节 #### 二、CStringCString是MFC提供的字符串处理类(`afx.h`中定义),封装了高级字符串操作: ```cpp CString str1 = _T("Windows"); CString str2 = _T("Programming"); str1 += _T(" ") + str2; // 结果:"Windows Programming" ``` **核心功能**: 1. **内存管理**:自动分配/释放内存 2. **操作符重载**:支持`+`, `=`, `==`等运算符 3. **常用方法**: ```cpp str.GetLength(); // 获取长度 str.MakeUpper(); // 转大写 str.Find('P'); // 查找字符位置 str.Format(_T("%d"), 100); // 格式化 ``` #### 三、相互转换方法 ##### 1. CString → TCHAR* (LPTSTR) **安全方法(推荐)**: ```cpp CString str = _T("Test"); TCHAR* pBuffer = new TCHAR[str.GetLength() + 1]; _tcscpy(pBuffer, str.GetString()); // 使用后必须释放内存! delete[] pBuffer; ``` **直接访问(需谨慎)**: ```cpp LPTSTR psz = str.GetBuffer(str.GetLength()); str.ReleaseBuffer(); // 必须成对使用[^2] ``` ##### 2. TCHAR* → CString ```cpp TCHAR* szText = _T("Hello"); CString str(szText); // 直接构造 // 或 str.Format(_T("%s"), szText); ``` ##### 3. CString ↔ 基本类型 **转换示例**: ```cpp // int → CString int nVal = 100; CString strInt; strInt.Format(_T("%d"), nVal); // CString → double CString strDouble = _T("3.14159"); double dVal = _tstof(strDouble); // char* → CString char* pAnsi = "ANSI Text"; CString strAnsi = CString(pAnsi); // ANSI版本[^3] ``` #### 四、跨平台兼容方案 对于非Windows平台,可参考标准C++实现: ```cpp // 伪代码参考 class CString { private: std::string m_data; // ANSI版本 std::wstring m_wdata; // Unicode版本 public: const TCHAR* GetString() const { #ifdef _UNICODE return m_wdata.c_str(); #else return m_data.c_str(); #endif } }; ``` #### 五、关键注意事项 1. **内存安全**: ```cpp // 错误示例:返回临时指针 TCHAR* DangerousFunc() { CString tmp = _T("Temp"); return tmp.GetBuffer(); // 临时对象销毁后指针失效! } ``` 2. **Unicode一致性**: - 项目属性设置需一致(_UNICODE/_MBCS) - 混合使用会导致乱码或崩溃 3. **API兼容**: ```cpp MessageBox(NULL, str.GetString(), _T("Title"), MB_OK); // 正确 MessageBox(NULL, str, _T("Title"), MB_OK); // MFC隐式转换 ``` ### 应用场景示例 **注册表读写**: ```cpp CString ReadRegValue(HKEY hKey, LPCTSTR lpSubKey) { TCHAR szValue[MAX_PATH] = {0}; DWORD dwSize = sizeof(szValue); RegGetValue(hKey, NULL, lpSubKey, RRF_RT_REG_SZ, NULL, szValue, &dwSize); return CString(szValue); // 自动转换 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值