引言
因为C语言风格的字符串容易出错且不易管理,黑客们甚至利用可能存在的缓冲区溢出bug把C语言风格的字符串作为攻击目标,所以出现了很多字符串封装类。不幸的是,在某些场合下我们不知道该使用哪个字符串类,也不知道怎样把一个C风格的字符串转换成一个字符串封装类。
这篇文章将介绍所有在Win32 API, MFC, STL, WTL 和 Visual C++ 运行库中出现的字符串类型。我将描述每一个类的用法,告诉大家怎样创建每一个类的对象以及怎样把一个类转换成其他类。受控字符串和Visual C++ 7中的类两部分是Nish完成的。
为了更好的从这篇文章中受益,你必须要明白不同的字符类型和编码,这些内容我在第一部分中介绍过。
Rule #1 of string classes
使用cast来实现类型转换是不好的做法,除非有文档明确指出这种转换可以使用。
促使我写这两篇文章的原因是字符串类型转换中经常遇到的一些问题。当我们使用cast把字符串从类型X转换到类型Z的时候,我们不知道为什么代码不能正常工作。各种各样的字符串类型,尤其是BSTR,几乎没有在任何一个地方的文档中被明确的指出可以用cast来实现类型转换。所以我想一些人可能会使用cast来实现类型转换并希望这种转换能够正常工作。
除非源字符串是一个被明确指明支持转换操作符的字符串包装类,否则cast不对字符串做任何转换。对常量字符串使用cast不会起到任何作用,所以下面的代码:
void SomeFunc ( LPCWSTR widestr );
main()
{
SomeFunc ( (LPCWSTR) "C:\\foo.txt" ); // WRONG!
}
肯定会失败。它可以被编译,因为cast操作会撤消编译器的类型检查。但是,编译可以通过并不能说明代码是正确的。
在下面的例子中,我将会指明cast在什么时候使用是合法的。
C-style strings and typedefs
正如我在第一部分中提到的,windows APIs 是用TCHARs来定义的,在编译时,它可以根据你是否定义_MBCS或者_UNICODE被编译成MBCS或者Unicode字符。你可以参看第一部分中对TCHAR的完整描述,这里为了方便,我列出了字符的typedefs
Type | Meaning |
WCHAR | Unicode character (wchar_t) |
TCHAR | MBCS or Unicode character, depending on preprocessor settings |
LPSTR | string of char (char*) |
LPCSTR | constant string of char (const char*) |
LPWSTR | string of WCHAR (WCHAR*) |
LPCWSTR | constant string of WCHAR (const WCHAR*) |
LPTSTR | string of TCHAR (TCHAR*) |
LPCTSTR | constant string of TCHAR (const TCHAR*) |