CString

MFC使用CString类提供了对字符串的支持。CString类可以单独应用于MFC框架的其他部分,因为他不是由CObject类派生的,但与大多数MFC对象一样,CString对象可以序列化。CString对象具有如下特性。

  • 可以使用CString对象任意替换Const char* 和LPCTSTR类型的函数参数。
  • CString对象遵循“值语义”,应将Cstring看做是一个真实的字符串而不是指向字符串的指针。
  • 通过转换操作符,可以直接访问该字符串的字符,就像访问一个只读字符数组一样。
  • CString大小可变,可以作为连接操作的结果而增大。
windows使用两种字符集ANSI 和UNICODE。微软提供了一些ANSI和UNICODE兼容的通用数据类型,最常用的由TCHAR,LPTSTR,LPCTSTR。CString是基于TCHAR数据类型的对象。

CString对象的内存分配

CString对象提供了动态内存分配,它是通过“引用”机制来管理分配的内存块。实际上CString对象只有一个指针成员变量,所以任何CString实例的长度只有4字节,即:

int len =sizeof(CString); //len=4

CString 类型转换

1、数值转换为字符

可以调用CString对象的Format方法格式化字符,如下面的代码:

CString str;

float f = 123.354;

str.Format(_T("显示浮点数:%f"),f);

2、CString转换为int

CString str("354");

itn iTemp = atoi(str);

如果准备使用Unicode字符,则应该使用_ttoi()函数,它在ANSI编码系统中被编译成_atoi(),在Unicode编码系统中编译成_wtoi(),如下面的代码:

CString str(_T("352"));

int iTemp = _ttoi(str);

CString 和char*相互转换

char* 转为CString非常简单:

char* p="this is a test";

CString s = p;                             //还可以表示为CString s(p);

CString 转为char*有下面几种方法

(1)、使用GetBuffer函数

char *p;

CString str="hello";

p = str.getBuffer(str.GetLength());

str.ReleaseBuffer();

(2)、使用memcpy函数

CString mCS =_T("cxl");

char mch[20];

memcpy(mch,mCS,mCS.GetLength());

(3)、使用LPCTSTR强制类型转换

char* ch;

CString str = _T("cxl");

ch = (LPSTR) (LPCTSTR) str;

<think>我们正在讨论的是TCHAR和CString的相关知识。根据之前的引用内容,我们可以总结出以下几点: 1. TCHAR是一种通用的字符类型,用于支持Unicode和多字节字符集(MBCS)。在编译时,根据是否定义了_UNICODE宏,TCHAR会被定义为wchar_t(Unicode)或char(MBCS)。 2. CStringMFC中用于处理字符串的类,它封装了字符串操作,并且可以自动处理内存分配和释放。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详解 CStringMFC中一个功能强大的字符串类,它提供了丰富的成员函数用于字符串操作。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字节 #### 二、CStringCStringMFC提供的字符串处理类(`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、付费专栏及课程。

余额充值