| Lei's profile踏遍青山人未老BlogNetwork | Help |
|
|
September 09 MS平台中一些字符串相关类型处理的小结【1】 前一段时间因为基于MFC和ATL做一点东西,被里面的字符串处理弄得几乎要吐血。。。没办法只好baidu+google+msdn。。。这样简单的事情都费了老大的功夫,看来以我的水准离程序员实在还是有很大差距。由此不由的向sphinx、clx、gy,以及MH、QLY和老Cao等致以崇高的敬意:何时才能修炼到你们的水准呐?!!! 这里就算是对相关字符串处理做一个小结,很多东西来源于Internet,我也尽可能将出处标明。怎么说也可算是半原创了吧,这可是开天辟地头一遭啊 以下是正文: 1. char, string和wchar_t, wstring C/C++标准最基本的情况大家耳熟能详,没有什么好说的,无非是char* 和 string类的转换问题。string在名为std的命名空间中提供,实际上是basic_string<char>,即basic_string模板类的char实例化。 从char*到string没的说,可直接利用构造函数;反过来从string到char*则一般依赖string类的成员函数c_str(),不过有个小问题,因为函数返回值是const char*,因此若要对其做改变还是自己copy一份比较稳当。 以上我们可以称之为ANSI标准,到这里其实问题不是太大,无非是某些字符串处理函数是否线程安全,是否会导致Buffer Overflow等等。这些安全方面的考量不在本文的考察范围之类,因此直接无视之。但众所周知ANSI是8bit的东西,容纳不下像天朝这么博大的文字。于是后来就有了Unicode,就有了wstring,其实这仅仅是模板类basic_string的wchar_t实例化而已。 PS:在VC的项目中,有选择“Use Unicode Character Set”或者“Use Multi-Byte Character Set” (MBCS)。这是两种不同的编码,前者都是两个字节,后者是混合型的(兼容ANSI,因此对英文来说没有区别)。在VC项目中的区别,据[1]说是区别在于前者编译器添加了“_UNICODE” 定义进行编译,而后者则没有这样的定义,一切依赖于“_UNICODE”的值,这样的话有个不错的变通方法,即按照VC中TCHAR的定义,自己定一个新 的类“tstring”,具体办法见[1]。 2. ANSI和Unicode之间的转换 如果ANSI和Unicode之间井水不犯河水,大家和平相处那就真的是天下太平啦。但人生不如意事十之八九,譬如不少软件系统,尤其是早期的版本很多建立在ANSI之上,为了跟上时代的脚步,需要向Unicode迁移;还有一些就是像我这样自作孽不可活的家伙,因为习惯于char*,于是不管三七二十一乱搞一通,后来发现某些东西(如COM)收礼只收Unicode。。。于是陷入没完没了的ANSI和Unicode之间的互相转换。。。泪流满面。。。 言归正传。事实上从原理来说ANSI和Unicode之间的转换其实很简单,无非是单字节双字节表示方法的变换而已。问题在于自己做这样的转换既不安全亦不可靠(NB人士除外)。为此,ANSI和Win32各自提供了一套转换方法[2]:
但上述函数,尤其是Win32的函数保持了一贯的参数冗长的特色,实在是麻烦的紧。于是在MFC和ATL中提供了一系列东西供大家使用。。。不过数目是多了一点,让人有目不暇接之感。MFC曾经比较基本和常用的就是: 1) A2CW (LPCSTR) -> (LPCWSTR) 2) A2W (LPCSTR) -> (LPWSTR) 3) W2CA (LPCWSTR) -> (LPCSTR) 4) W2A (LPCWSTR) -> (LPSTR) 这里LPCSTR即const char*, LPCWSTR指的是const wchar_t*,中间的C指的是const。。。依次类推。这四个都是宏,是基于MultiByteToWideChar WideCharToMultiByte两个函数或衍生函数之上的。 不过列为看官,以上四个那都是老黄历了,(如果没有搞错的话。。。)自ATL 7.0之后定义了新的模板类以及基于这些模板类的宏,供MFC和ATL使用,MSDN给出的格式形如:CSourceType2[C]DestinationType[EX]。譬如CA2W,CW2CA等等。第一个C并非是指const,而是代表Class(个人感觉Convert更贴切^_^):
一般来说,我们大都使用通过typedef CA2WEX<> CA2W来定义的CA2W以及对应的CW2A。没有EX表示使用默认的缓冲区大小。这里的陷阱在于:由于返回的字符串的空间是在栈中分配的,因而它不能直接作为函数的返回值。 PS: [2]提到Linux没有实现ANSI的这一套函数其实并不确切,[3]对此有一些解释。 References: 1. http://msdn.microsoft.com/en-us/magazine/cc188714.aspx 2. http://dev.csdn.net/article/45/45124.shtm 3. http://aaronike.spaces.live.com/blog/cns!437ebac13d3cefcd!120.entry Comments (12)
TrackbacksThe trackback URL for this entry is: http://cid-e161eb52ad524ac0.spaces.live.com/blog/cns!E161EB52AD524AC0!257.trak Weblogs that reference this entry
|
|
|