在windows C++的环境下,会接触到好多种字符串类型:
C++的std::string
, std::wstring
, char*
, wchar*
, windows的LPCTSTR
,MFC的CString
…
先来说说C++入门时最早接触的: std::string
类和char*
string
是一个类,用起来非常方便,char*
转成std::string
的几种方法:
char szName[100] = "abcde\0123";
string str1 = szName; //str1是abcde
string str2(szName); //str2是abcde
string str3(szName, 9); //str3是abcde\0123, 该构造函数常用于保存二进制数据
这里要注意一点对比,就是:
string (const char* s);
该构造函数的意思是:Copies the null-terminated character sequence (C-string) pointed by s.
string (const char* s, size_t n);
而这个构造函数的意思是:Copies the first n characters from the array of characters pointed by s. 可以用于二进制数据的拷贝。可以参考用string存取二进制数据
这2个东西其实很类似的,重要的是: 编码格式一致:ANSI, 也就是用的ASCII编码。
char*
可以方便地生成string
, string
也可以方便地转化成char*
:
std::string str = "abc";
char* szName = str.c_str();
更多资料,可以查看C++ reference
而wstring
就是string
的变种,使用的是Unicode编码,2个字节,所以wchar
占用2个字节。
wstring
与wchar*
的关系 和 string
与char*
的关系是一样的。wstring
就可以用来表示中文字符。
wstring
类拥有的成员函数, wchar*
的函数 和 string
以及char*
几乎都是一样的。
那么就有一个问题,string
和wstring
如何互相转化呢。
就需要用到Windows API函数MultiByteToWideChar
,一般需要使用2次:
#define CP_ACP 0 // default to ANSI code page
void ConvertAnsiTounicode(char * source,TCHAR * dst)
{
int nLength = 0;
nLength = MultiByteToWideChar(CP_ACP,0,source,-1,NULL,0);
MultiByteToWideChar(CP_ACP,0,source,-1,dst,nLength);
}
函数MultiByteToWideChar
使用不当,会影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr
指向的输入缓冲区大小是宽字符数,而lpMultiByteStr
指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。方法是先使cbMultiByte
为0调用WideCharToMultiByte
一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte
填充缓冲区。
那么wstring也
可以转化到string
, 就是一个反过来的API:WideCharToMultiByte
, 用法也类似。
那么LPCTSTR
呢,分2种情况: LPCSTR
和LPCWSTR
,其实只是微软的宏定义,说白了就是const char*
和const wchar*
,不要被吓坏了!!!所以直接当成const char*
和const wchar*
使用就行了。
剩下一个就是MFC的CString
, 它也分2种: CStringA
和CStringW
首先,CString
可以直接强转成LPCTSTR
。也就是说(以下代码为Unicode版本),
CString Cstr = L"lalala";
const wchar_t* = (LPCTSTR)Cstr;
可以这样玩。
也就是CString
和wchar_t*
可以直接转换啦。那么std::wstring
和CStringW
也能互相转换:
CString
转成std::wstring
, 一行代码搞定,有wchar_t*
这个中介:
std::wstring str = (LPCTSTR)(Cstr);
std::wstring
转成CString
:
CString Cstr(wstr.c_str());
即可。那么CStringA
和std::string
也可以通过中介char*
来互相转换成功的。
最后附上一张图, 联想MFC中的宏(A2W
, W2T
之类的):