|
以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- C++字符串完全指引之二 —— 字符串封装类 (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=40528) |
|
-- 作者:卷积内核 -- 发布时间:11/27/2006 9:47:00 AM -- C++字符串完全指引之二 —— 字符串封装类 引言 因为C语言风格的字符串容易出错且不易管理,黑客们甚至利用可能存在的缓冲区溢出bug把C语言风格的字符串作为攻击目标,所以出现了很多字符串封装类。不幸的是,在某些场合下我们不知道该使用哪个字符串类,也不知道怎样把一个C风格的字符串转换成一个字符串封装类。 Rule #1 of string classes 使用cast来实现类型转换是不好的做法,除非有文档明确指出这种转换可以使用。 void SomeFunc ( LPCWSTR widestr ); Type Meaning 一个增加的字符类型是OLETYPE。它表示自动化接口(如word提供的可以使你操作文档的接口)中使用的字符类型。这种类型一般被定义成wchar_t,然而如果你定义了OLE2ANSI预处理标记,OLECHAR将会被定义成char类型。我知道现在已经没有理由定义OLE2ANSI(从MFC3以后,微软已经不使用它了),所以从现在起我将把OLECHAR当作Unicode字符。 Type Meaning 还有两个用于包围字符串和字符常量的宏定义,它们可以使同样的代码被用于MBCS和Unicode builds : Type Meaning 在文档或例程中,你还会看到好多_T的变体。有四个等价的宏定义,它们是TEXT, _TEXT, __TEXT和__T,它们都起同样的做用。 COM 中的字符串 —— BSTR 和 VARIANT 很多自动化和COM接口使用BSTR来定义字符串。BSTRs中有几个"陷阱",所以这里我用单独的部分来说明它。
06 00 00 00 42 00 6F 00 62 00 00 00 注意字符串的长度是如何被加到字符串数据中的。长度是DWORD类型的,保存了字符串中包含的字节数,但不包括结束标记。在这个例子中,"Bob"包含3个Unicode字符(不包括结束符),总共6个字节。字符串的长度被预先存储好,以便当一个BSTR在进程或者计算机之间被传递时,COM库知道多少数据需要传送。(另一方面,一个BSTR能够存储任意数据块,而不仅仅是字符,它还可以包含嵌入在数据中的0字符。然而,由于这篇文章的目的,我将不考虑那些情况)。 BSTR bstr = NULL; 字符串封装类 到目前为止,我已经介绍了各种各样的字符串。下面,我将说明封装类。对于每个封装类,我将展示怎样创建一个对象及怎样把它转换成一个C语言风格的字符串指针。C语言风格的字符串指针对于API的调用,或者创建一个不同的字符串类对象经常是必需的。我不会介绍字符串类提供的其他操作,比如排序和比较。 CRT提供的类 _bstr_t _variant_t 还需要注意的是: |
|
-- 作者:卷积内核 -- 发布时间:11/27/2006 9:48:00 AM -- STL 类 STL只有一个字符串类,basic_string。一个basic_string管理一个以0做结束符的字符串数组。字符的类型是basic_string模般的参数。总的来说,一个basic_string类型的变量应该被当作不透明的对象。你可以得到一个指向内部缓冲区的只读指针,但是任何写操作必须使用basic_string的操作符和方法。 basic_string有两个预定义的类型:包含char的string类型和包含wchar_t的wstring类型。这里没有内置的包含TCHAR的类型,但是你可以使用下面列出的代码来实现。 // Specializations typedef basic_string tstring; // string of TCHARs // Constructing string str = "char string"; // construct from a LPCSTR wstring wstr = L"wide char string"; // construct from a LPCWSTR tstring tstr = _T("TCHAR string"); // construct from a LPCTSTR // Extracting data LPCSTR psz = str.c_str(); // read-only pointer to str''s buffer LPCWSTR pwsz = wstr.c_str(); // read-only pointer to wstr''s buffer LPCTSTR ptsz = tstr.c_str(); // read-only pointer to tstr''s buffer 不像_bstr_t,一个basic_string变量不能在字符集之间直接转换。然而,你可以传递由c_str()返回的指针给另外一个类的构造函数(如果这个类的构造函数接受这种字符类型)。例如: // Example, construct _bstr_t from basic_string _bstr_t bs1 = str.c_str(); // construct a _bstr_t from a LPCSTR _bstr_t bs2 = wstr.c_str(); // construct a _bstr_t from a LPCWSTR ATL 类 CComBSTR bs4.LoadString ( IDS_SOME_STR ); // load string from string table CComVariant // Constructing ATL转换宏 ATL:转换宏是各种字符编码之间进行转换的一种很方便的方式,在函数调用时,它们显得非常有用。ATL转换宏的名称是根据下面的模式来命名的[源类型]2[新类型]或者[源类型]2C[新类型]。据有第二种形式的名字的宏的转换结果是常量指针(对应名字中的"C")。各种类型的简称如下: // Functions taking various strings: |
|
-- 作者:卷积内核 -- 发布时间:11/27/2006 9:50:00 AM -- MFC类 CString CString CLR 和 VC 7 类 System::String是用来处理字符串的.NET类。在内部,一个String对象包含一个不可改变的字符串序列。任何对String对象的操作实际上都是返回了一个新的String对象,因为原始的对象是不可改变的。String的一个特性是如果你有不止一个String对象包含相同的字符序列,它们实际上是指向相同的对象的。相对于C++的使用扩展是增加了一个新的字符串常量前缀S,S用来代表一个受控的字符串常量(a managed string literal)。 在 printf-style 格式函数中使用字符串类 当你在printf()或者类似的函数中使用字符串封装类时你必须十分小心。这些函数包括sprintf()和它的变体,还有TRACE和ATLTRACE宏。因为这些函数没有对添加的参数的类型检查,你必须小心,只能传给它们C语言风格的字符串指针,而不是一个完整的字符串类。 所有类的总结 两个字符串类之间进行转换的常用方式是:先把源字符串转换成一个C语言风格的字符串指针,然后把这个指针传递给目的类型的构造函数。下面这张表显示了怎样把一个字符串转换成一个C语言风格的字符串指针以及哪些类具有接收C语言风格的字符串指针的构造函数。 Class string type convert to char*? convert to const char*? convert to wchar_t*? convert to const wchar_t*? convert to BSTR? construct from char*? c onstruct from wchar_t*? |
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
5,093.750ms |