CString string char TCHAR 之间的转换
最近在VS2015 下写MFC的程序,发现VS里面UNICODE编码下 字符串转换很麻烦,于是自己搜索加测试总结了一下。
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
typedef unsigned char CHAR;
typedef unsigned wchar_t WCHAR;
由此可以看出,CHAR实施上就是unsignedchar,WCHAR为宽字符,而TCHAR根据是否支持unicode而不同。在程序使用sizeof(TCAHR),当默认设置时,这个值是1;当定义UNICODE宏时,这个值是2。
TCHAR是一种字符类型,它让你在以MBCS和UNNICODE来build程序时可以使用同样的代码,不需要使用繁琐的宏定义来包含你的代码,而char代表ASCII的字符
所以用MBCS来build时,TCHAR是char,使用UNICODE时,TCHAR是wchar_t.
至于String,CString他们都是一种封装了字串处理的操作!
你可以打开他们的源代码找寻究竟!
CString属于VC的类库
string是标准C++的类库
string.h是C的库函数。
LPSTR:32bit指针指向一个字符串,每个字符占1字节
LPCSTR:32-bit指针指向一个常字符串,每个字符占1字节
LPCTSTR:32-bit指针指向一个常字符串,每字符可能占1字节或2字节,取决于Unicode是否定义
LPTSTR:32-bit指针每字符可能占1字节或2字节,取决于Unicode是否定义
在UNICODE编码下类似于
LPCSTR : const CHAR*
LPSTR: CHAR*
LPCTSTR: const TCHAR *
LPTSTR: TCHAR *
//测试
LPCTSTR pL1 = L"1234";
TCHAR* pT1 = L"5678";
pL1 = pT1;
LPTSTR pL2 = L"1234";
pL1 = pL2;
类型
char:单字节变量类型,最多表示256个字符。
wchar_t :宽字体变量类型,用于表示Unicode字符。
它实际定义在<string.h>里,typedef unsigned short wchar_t.
为了让编译器识别Unicode字符串,必须在前面加一个“L”,定义宽字节类型的方法为:
wchar_t c=L’A’;
wchar_t *p=L”Hello!”;
宽字节类型每个变量占用2个字节。
TEXT
windows头文件中提供了TEXT宏可以视UNICODE宏是否定义来自动切换由其定义的字符串,其定义大体如下:
#ifdef UNICODE
#define TEXT(s) L##s
#else
#define TEXT(s) s
#endif
##为宏定义中使用的拼接符
使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:
1、只适合于进行短字符串的转换;
2、不要试图在一个次数比较多的循环体内进行转换;
3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;
4、对情况 2 和 3,要使用 MultiByteToWideChar() 和WideCharToMultiByte();
使用 ATL 提供的转换宏。
A2BSTR | OLE2A | T2A | W2A |
A2COLE | OLE2BSTR | T2BSTR | W2BSTR |
A2CT | OLE2CA | T2CA | W2CA |
A2CW | OLE2CT | T2COLE | W2COLE |
A2OLE | OLE2CW | T2CW | W2CT |
A2T | OLE2T | T2OLE | W2OLE |
A2W | OLE2W | T2W | W2T |
上表中的宏函数,其实非常容易记忆:
2 | 好搞笑的缩写,to 的发音和 2 一样,所以借用来表示“转换为、转换到”的含义。 |
A | ANSI 字符串,也就是 MBCS。 |
W、OLE | 宽字符串,也就是 UNICODE。 |
T | 中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A |
C | const 的缩写 |
UNICODE 编码方式(VS2015)
USES_CONVERSION;//只调用一次即可 多次会报错
CString转换为const char*
CString CStr1 = _T("1234");
const char* pC = T2A(CStr1);//注意PC指向区域在栈空间
const char* 转换为CString
CString CStr2 = A2T(pC);
CString 转TCHAR*
TCHAR* pT1 = nullptr;
pT1= new TCHAR[CStr1.GetLength()+1];
//pT1=CStr1.GetBuffer();这样也可以
lstrcpy(pT1,CStr1.GetBuffer());
CStr1.ReleaseBuffer();
TCHAR* 转CString
CStr2.Format(_T("%s"),pT1);
constchar* 转string
const char* p = "abcd";
string str1 = p;
string 转const char*
p =str1.c_str();
String转CString
CString CStr3;
CStr3= str1.c_str();//赋值运算符重载了
CString 转string
string str2;
str2= T2A(CStr3);
//下边是从别人博客借鉴
TCHAR* 转char*
char* CPublic::THCAR2char(TCHAR*tchStr)
{
int iLen = 2*wcslen(tchStr);//CString,TCHAR汉字算一个字符,因此不用普通计算长度
char* chRtn = new char[iLen+1]
wcstombs(chRtn,tchStr,iLen+1);//转换成功返回为非负值
return chRtn;
}
char* 转TCHAR*
TCHAR *char2tchar(char *str)
{
int iLen =strlen(str);
TCHAR *chRtn = newTCHAR[iLen+1];
mbstowcs(chRtn,str, iLen+1);
return chRtn;
}
//下边两种只是作为了解有上边几种也完全足够(不会转化时 使用内存拷贝)
wchar_t* 转化为char*
char* WcharToChar(const wchar_t* wp)
{
char *m_char;
int len = WideCharToMultiByte(CP_ACP, 0, wp, wcslen(wp), NULL, 0, NULL, NULL);
m_char = new char[len + 1];
WideCharToMultiByte(CP_ACP, 0, wp, wcslen(wp), m_char, len, NULL, NULL);
m_char[len] = '\0';
return m_char;
}
char* 转化为wchar_t
wchar_t* CharToWchar(const char* c)
{
wchar_t *m_wchar;
int len = MultiByteToWideChar(CP_ACP, 0, c, strlen(c), NULL, 0);
m_wchar = new wchar_t[len + 1];
MultiByteToWideChar(CP_ACP, 0, c, strlen(c), m_wchar, len);
m_wchar[len] = '\0';
return m_wchar;
}