作者目前处于学习状态,文中难免会有错误或者不妥之处,欢迎各位读者在评论区里纠正
1 为何C++会有那么多"字符串"
你印象中C++的字符串应该是:
char[],char *,string
而实际项目中你可能遇到的字符串却是:
TCHAR,wchar_t *,CString,LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,_T(“Hello World”), L"Hello World",…
C++之所以出现那么多字符串,原因
其实很简单:Windows使用了两种字符集ANSI和UNICODE,而C++需要去兼容
。
2 字符集
ANSI
:单字节,通常使用的方式,但这种方式处理象中文这样的双字节字符不方便,容易出现半个汉字的情况,char 使用的是该字符集。
UNICODE
:双字节,单字节只有8个位,只能包含256个字符,而像很多外文字符远超过256个字符,例如:中文、日文、韩文等,这些字符需要占用两个字节空间,所以c++提出了双字节字符类型wchar_t(或叫宽字符类型)。
3 CString、LPSTR、LPTSTR、LPWSTR…
首先说明:
- 'L’代表
Long
,'P’代表Pointer(指针)
,'STR’表示String
,'W’代表Width
,‘T’:win32中的有个_T宏
,用来标识字符是否采用Unicode编码
。 _T
:如果你编译一个程序为ANSI方式,_T实际不起任何作用,编译器会把_T(“Hello”)以ANSI方式保存。而如果编译一个程序为UNICODE方式,则编译器会把_T(“Hello”)字符串以UNICODE方式保存L(变量声明中)
:L不管你是以什么方式编译,一律以UNICODE方式保存。TCHAR,CString,LPSTR,LPCSTR
等包含在头文件atlstr.h
中
有了上面的说明,一切就变的很简单了
3.1 单字节
char
: 单字节字符
char []
: 字符数组(作者目前理解为不可修改
的字符串)
char *
: 指向一个char类型的指针(作者目前理解为可修改
的字符串)
LPSTR
: char * 的别名
const char *
:指向一个具有const限定符的char类型的指针(作者目前理解为不可修改
的字符串)
LPCSTR
: const char * 的别名
string
:是std::basic_string模板类的实例化,是一个类(C++的STL才有),string str=“aaa”; 其实是 const char *转class ,string重载了=号,把“aaa”封装成std::string
//字符串定义
char s1[] = "Hello World";
string s2 = "Hello World";
char* s3 = (char*)"Hello World";//新版本的C++貌似char * 不能直接转const char *
LPSTR s4 = (char*)"Hello World";
const char* s5 = "Hello World";
LPCSTR s6= "Hello World";
//获取类型
cout << typeid(s1).name() << endl;
cout << typeid(s2).name() << endl;
cout << typeid(s3).name() << endl;
cout << typeid(s4).name() << endl;
cout << typeid(s5).name() << endl;
cout << typeid(s6).name() << endl;
//字符串拼接
string res = s + (string)" " + (string)str;
cout << res << endl;
3.2 _T编码字节
TCHAR
: 根据程序字符集来确定是但字节字符(ANSI)还是双字节字符(UNICODE)
CString
:MFC中,基于TCHAR封装的字符串类
TCHAR[]
,TCHAR *
,const TCHAR *
: 区别类比单字节
LPTSTR
: TCHAR* 的别名
LPCTSTR
: const TCHAR* 的别名
TCHAR t1[] = _T("Hello World");
CString t2 = "Hello World";
TCHAR* t3 = (TCHAR*)_T("Hello World");
LPTSTR t4 = (TCHAR*)_T("Hello World");
const TCHAR* t5 = _T("Hello World");
LPCTSTR t6= _T("Hello World");
wstring res = t2 + t4;
wcout << res << endl;
3.3 双字节
wchar_t
: 双字节字符
wstring
、wchar_t []
、const wchar_t
,wchar_t *
:区别类比单字节
LPWSTR
: wchar_t * 的别名
LPCWSTR
: const wchar_t * 的别名
wchar_t w1[] = L"Hello World";
wstring w2 = L"Hello World";
wchar_t* w3= (wchar_t *)L"Hello World";
LPWSTR w5 = (wchar_t*)L"Hello World";
const wchar_t* w4 = L"Hello World";
LPCWSTR w6 = L"Hello World";
CString res1 = t5 + (CString)_T(" ") + t1;
wcout << res1.GetString() << endl;
wstring res = w2 + w4;
wcout << res << endl;
4 字符串的相互转换
4.1 string和CString互转
//string->Cstring
string str = "string to CString";
CString cstr(str.c_str());
wcout << cstr.GetString() << endl;
//CString->string
CString theCStr = L"Hello C++";
std::string str2(CW2A(theCStr.GetString()));
cout << str2 << endl;
4.2 char* 和 wchar_t * 互转
//char* 转wchar_t *
wchar_t* result;
char* arr = (char *)"Hello World";
size_t len = strlen(arr) + 1;
size_t converted = 0;
result = (wchar_t*)malloc(len * sizeof(wchar_t));
mbstowcs_s(&converted, (wchar_t*)result, len, arr, _TRUNCATE);
wcout << result<<endl;
//wchar_t* 转 char*
int iSize;
char* result;
wchar_t* wstr = (wchar_t*)L"Hello World";
iSize = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
result = (char*)malloc(iSize * sizeof(char));
WideCharToMultiByte(CP_ACP, 0, wstr, -1, result, iSize, NULL, NULL);
cout << "value:" << result << endl;