1.基本概念
2.L与_T
3.char TCHAR 与 wchar_t,strcpy wcscpy与_tcscpy
4.LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR
5.ANSI转Unicode(char 转 wchar_t)
6.Unicode转ANSI(wchar_t 转 har)
7.CString
1.ANSI与Unicode
ANSI:多字节字符集,采用不定长编码方式,存储英文字符时一个字节对应
一个字符,而存储中文汉字时一个汉字采用两个字节存储。我们GB2312就是
采用多字节字符集
1.1 多字节字符集(ANSI): 在vs2017环境下,项目—>属性—>字符集 选择使用多字节字符集
使用多字节字符集存编码方式存储英文字符串,我们可以清楚的看到一个字节存储一个字符。
多字节字符集存储中文汉字
1.2:Unicode字符集:Unicode字符集采用的是定长编码,无论是英文字符还是
汉字,都是两个字节存储一个字符。
在 项目->属性->字符集 处选用Unicode字符集,确定。
使用Unicode字符集,存储英文字符串时内存如图所示:我们在地址0x00d9edb4处存储了字符串“FFFEFBF0”,查看该地址处的内存,发现存储的是46 00 46 00 46 00 45 00 46 00 42 00 46 00 30 00,两字节存储和一个字符,高位用0填充。
在使用Unicode字符集的条件下存储汉字,与多字节字符集是一样的。
1.3 如何区分文本是ANSI还是Unicode编码?
文本文件开头两个字节是0xFF和0xFE就是Unicode,否则是ANSI。
1.4 如何判断一个字符串是ANSI还是Unicode编码?
用IsTextUnicode进行判断
2.L与_T
2.1 Unicode.L
L表示字符串资源采用Unicode编码方式,无论我们使用的是多字节字符集
还是Unicode字符集,L“字符串”都将采用Unicode的编码。
如图,在没有使用L时中文编码使用的是GBK。
无论我们使用的是多字节字符集还是Unicode字符集 ,使用L时字符串编码变成了Unicode编码 ,至于char* 与wchar_t * 的区别见下一节
2.2 _T也同字符常量相关,编码方式为多字节字符集时没有任何作用,如图所示:此时的编码方式和没有使用L和_T时是一样的。
编码方式为Unicode 时_T的作用和L的作用一致
3.char TCHAR 和 wchar_t , strcpy wcscpy和_tcscpy
char不用多说,字符型,单位是字节。
wchar_t是Unicode的数据类型,定义在<string.h>中,单位双字节,
在ANSI中使用wchar_t报错。wchar_t的类型的字符是按照Unicode
的编码方式存储。
给wchar_t类型变量赋值时,要注意类型以及编码方式是否匹配。wchar_t *str=L"aaabbb"; str是wchar_t类型,而wchar_t是Unicode的数据类型,所以后面的"aaabbb"要用L将其转换成Unicode编码。
TCHAR是一个宏,并不是实际的某一类型,当使用多字节字符集时,TCHAR就
是char,当字符集使用的是Uncode字符集时,TCHAR可以当成wchar_t来使用,
这也是TCHAR的意义所在,我们不用具体细分我们改用char还是wchar_t,直
接 使用TCHAR,编译器会根据我们字符集来进行相应的转化。TCHAR定义在
<TChar.h>中,所以如果要使用TCHAR,首先要包含头文件<TChar.h>
图(Unicode字符集)
strcpy函数是c语言的一个标准库函数,功能是复制字符串,返回值类型为
char*,多字节字符集编码使用strcpy函数,Unicode字符集使用wcscpy,
_tcscpy函数和TCHAR,_T是一样的,是一个中间体,根据我们使用的
字符集的不同来向两边转化。
这里有可能会对_T, TCHAR, _tcscpy有点不理解,它们的作用究竟是什么,不显得很多余吗?其实很简单,比如我们使用的是Unicode字符集,那么我们使用的编码就是Unicode编码,此时使用的字符类型是wchar_t, L"字符串"是将该字符串用Unicode编码的方式存储,但是同一套代码,如果我们将它放在多字节字符集的环境下,就会出现错误。
而如果我们使用的是中间类型THCAR, 配套的使用_T代替L,_tcscpy取代wcscpy,那么无论我们使用的是Unicode字符集还是多字节字符集,系统会自动根据我们的环境做出相应的变化从而能够同时满足Unicode编码和ANSI编码。
4.LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR
LPSTR:32bit指针 指向一个字符串,每个字符占1字节。相当于 char *
LPCSTR:32-bit指针 指向一个常字符串,每个字符占1字节。相当于 const char *
LPTSTR:32-bit指针 每字符可能占1字节或2字节,取决于Unicode是否定义
LPCTSTR:32-bit指针 指向一个常字符串,每字符可能占1字节或2字节,取决于Unicode是否定义
LPWSTR: 32-bit指针,指向一个unicode字符串的指针,每个字符占2字节。
LPCWSTR:32-bit指针, 指向一个unicode字符串常量的指针,每个字符占2字节。
能看懂,记不住?分不清?让我们开看看每个字母的含义:
LP:long pointer,长指针,表示这是一个指针类型。
C:constant,常量,表示用该类型定义的变量只可赋初值不可修改
T: 这个T和上面的TCHAT,_T等是一套东西,表示取决于Unicode是否定义。
W:wide,表示Unicode编码,两个字节一个字符
STR:string。
由此我们可以得到
LPSTR 等于 char*
LPCSTR 等于 const char*
LPTSTR 等于 tchar*
LPCTSTR 等于 const tchar*
LPWSTR 等于 wchar_t*
LPCWSTR 等于 const wchar_t*
看看它们的定义:
5.ANSI转Unicode
5.1 MultiByteToWideChar函数
char szANSIString[20] = "ffbabbdd";
wchar_t szwString[40];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szANSIString, -1, szwString, sizeof(szwString));
5.2 A2W
A2W,W2A, A2T,T2A的用法
6.Unicode转ANSI
6.1 WideCharToMultiByte函数
WideCharToMultiByte
6.2 W2A
A2W,W2A, A2T,T2A的用法
CString
在ANSI和Unicode下是如何编码的
CString str0 = _T("aabbcc");
char *strChar0 = "aabbcc";
wchar_t *strWChar0 = L"aabbcc";
CString str = _T("你好");
char *strChar = "你好";
wchar_t *strWChar = L"你好";
根据测试我们可知知道得到CString也是和根据否使用Unicode字符集来调整编码方式的。等价于TCHAR*