windows中的字符串类型
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Windows字符串类型
C++主要使用的是C-Style字符串,而M$在Windows中又增加了很多C-Style字符串的变体。这个一多嘛,就容易乱~
所谓字符串,就是由字符组合而成,所以我们先来将将字符类型。
首先,存在两种最基本的字符类型:char和wchar_t。char大家都很熟悉了,我就跳过。至于wchar_t,是应用于UNICODE的宽字符,即一个字符2Bytes,16Bits。事实上,Windows 中利用
typedef unsigned short wchar_t
定义wchar_t
然后为了书写方便(MS我也没觉得有多大差别),M$又把那两个基本字符类型重新的给他typedef了一遍,即:
typedef char CHAR
typedef wchar_t WCHAR
为了使得兼容性更加,M$又定义了TCHAR数据类型:
#ifdef UNIOCDE
typedef WCHAR TCHAR
#else
typedef CHAR TCHAR
#endif
这样,你不用关心是要使用ANSI字符串还是Unicode,编译器会自动根据你的OS来选择。
然后,M$又利用上面的几种基本数据类型,定义了一些字符串指针类型。
LPSTR和LPCSTR:LPSTR是指向以0结尾的ANSI字符串的指针,后者是const指针typedef CHAR* LPSTR
typedef const CHAR* LPCSTR
LPWSTR和LPCWSTR:LPWSTR是指向以0结尾的UNICODE字符串的指针,后者是const 指针
typedef WCHAR* LPWSTR
typedef const WCHAR* LPCWSTR
同样,为了摆脱对ANSI还是UNICODE的选择麻烦,M$也增加了LPTSTR和LPCTSTR两个字符串指针类型。他们被如下定义:
typedef TCHAR* LPTSTR
#ifdef UNICODE
typedef LPWSTR LPTSTR
#else
typedef LPSTR LPTSTR
#endif
/////////////////////////////////////
typedef const TCHAR* LPCTSTR
#ifdef UNICODE
typedef LPCWSTR LPCTSTR
#else
typedef LPCSTR LPCTSTR
#endif
ps:你会在某些地方看到存在PSTR/PWSTR/PTSTR等等,与上面的只却一个L的字符串指针类型。实际上,这个是长指针和短指针问题。LPXX是长指针,PXX是短指针。不过在32Bit 的系统上,二者已经没有区别。
然后说说两个比较成熟好用的字符串类型:String和CString
String是C++的标准字符串,需要string(不带.h)头文件和std名字空间支持。
CString是M$为MFC设计的字符串,功能更加强大,而且这玩意儿是安全的。需要atlstr.h 文件和MFC DLL的支持。不过目前已经有人将此类型从MFC中分离~
为了增强程序的通用性,还必须注意以下几点:
1、既然程序里不能出现char,那表示字符串时,就不能再习惯性的用char*了。应该改为TCHAR*,或者是PTSTR。后一种是 windows的变量,类似的有:PSTR、PTSTR、LPTSTR、LPSTR、PCTSTR等等等等。这也是让人一开始接触会头大的地方。其实并非如此恐怖,我以PCTSTR为例做个解释:P代表指针(和LP是一个东西,LP的本意是Long Pointer,16
位windows时代的遗留物。),C代表const,T代表TCHAR,STR代表字符串。所以PCTSTR 其实就是const TCHAR* 的意思。而PSTR也就是char* 的意思。所以我们在表示字符串时也不能使用PSTR等不带T的变量类型名。
2、表示字符串常量时,不能简单的用双引号括起来,因为那代表ascii字符串。同样也不能在前面加L,因为那代表unicode。我们的程序要做到的是通用性,即不是ascii也不是unicode。所以我们在字符串前应该加的是TEXT,比如
MessageBox(NULL,TEXT("Fypher"),TEXT("FF"),MB_OK)。TEXT还可用于字符。比如TCHAR m=TEXT('A');
3、TCHAR FF[50]。FF能装多少字符?哈!不要习惯性的sizeof(FF)了,应该_countof(FF)或者sizeof(FF)/sizeof(TCHAR)。因为我们不确定TCHAR到底是char 还是 wchar_t。
4、该和一堆老朋友说再见了……我们不能再使用以前的字符串处理函数或者字符处理函数了。比如strlen、strcat、strcmp等等等等……因为这些是ascii专用的,通通改成使用T家族的吧。前缀都换成_tcs。比如_tcslen、_tcscat、_tcscmp等等……顺便补充一下wcs前缀是wchar_t使用的。恩,还有大家用得超爽的sprintf,今后就改成_stprintf了吧~呵呵。补充:swprintf是 wchar_t它家的。对了,windows认为_tcscpy、_tcscat等不安全,所以使用这些函数编译器会报警。可以改用windows推出的 _tcscpy_s、_tcscat_s等“安全”函数,
其实就是多了个参数用来指明缓冲区大小(记得用_countof哦~!^_^)。windows 还推出了形如StringCchCat的一套字符串处理函数,我没怎么用过。windows也有一个字符串比较函数CompareString。功能比 _tcscmp强大多了。比如可以设置忽略大小写等。
5、IsTextUnicode函数可以用过一系列统计学的方法判断某个字符串是不是unicode字符串。 MultiByteToWideChar和WideCharToMultiByte函数可实现Ascii和Unicode字符串的相互转化。这些的使用场合都不大。因为我们的程序应该做到“没有”ascii和unicode。
6、虽然绝大多数情况下应该使用TCHAR,但是记住GetProcAdress这个特殊的函数吧,它的参数只能是char*。因为在导出函数表里函数名是用ascii码写的……
7、最后一点,记得要#include
8、注意:str前缀与wcs前缀都是标准C函数,需要有标准C运行库才能够使用。而lstr 前缀的是window提供的原生函数,不需标准C运行库。
9、如何对Unicode进行操作?
字符集特性实例
ANSI 操作函数以str开头 strcpy
Unicode 操作函数以wcs开头 wcscpy
MBCS 操作函数以_mbs开头 _mbscpy
ANSI/Unicode 操作函数以_tcs开头 _tcscpy(C运行期库)
ANSI/Unicode 操作函数以lstr开头 lstrcpy(Windows函数)
所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI 版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE