1、问题由来
同事突然问我是否遇到这样一个问题,在通过 “•” 分割 CATUnicode 字符串 “D•Cd5•D” 时 , 发现使用SearchSubString函数查找字符 “•” 失败, 通过cout 输出 为 “D?Cd5?D” ,通过SearchSubString(“?”)查找 同样失败。
2、解决过程
首先的想到的原因是字符编码问题,果断写了一测试程序。
CATUnicodeString ustr2Cut( "D•Cd5•D") , ustrToken("•") ;
if(-1 != SearchSubString(ustrToken)) { cout<<"Find"<<endl;}
没错,结果可以找到字符“•”,完成字符串的分割。
可是,同事的应用场景是 字符串“D•Cd5•D” 动态获取为CATUnicodeString 。再次搭建测试场景,发现动态获取字符串后确实无法查找到“•” 在字符串中的位置,而且 “•” 都输出为 “?” 。
这时 同事说他找到办法了 ,说只要将字符串转换成其它编码 再转回到CATUnicodeString 就可以 通过查找“•” 实现 字符串的分割。 我 测试的 情况是 将字符串 ConverToChar ,再 BuildFromChar 转成 CATUnicodeString , 同样的将“•” 做相同的变换,真的可以将字符串 分割开来。
3、原因分析
虽然同事的困扰解决了,但是我不认为这是正确的解决方法,再做如下测试:
用ustr2Cut.SearchSubString("?") 发现 返回结果不是 -1 , 即字符串中存在了字符 "?"。 这也说明将字符串ConvertToChar 再BuildFromChar 这种方法在本职上是不对的。通过查阅资料,原来是字符集中不存在时, ConvertToChar 会将字符集中不存在的字符转换成"?" 并替换原来的字符。
4、继续寻找
那真正的解决方法应该是什么?
动态获取的字符串 “D•Cd5•D” 是 Unicode 编码,我们SearchSubString(“•”)时 , 用到的“•” 在代码中 实际已经被"?"所替代,所以SearchSubString(ustrToken) 返回值是 -1 ,即并未找到“•” 。
所以,正确的做法是 查询 “•” 的ASICC 编码 ,然后通过编码构建 CATUnicodeString ustrToken2 作为分割符 ,再次 ustr2Cut.SearchSubString(ustrToken2 ), 可以正确查找到字符串中 分割符的位置 。
推荐小工具:
https://tool.oschina.net/encode
总结
问题虽然解决也找到了方法,可是奇怪的地方是中文字符可以正常的输出,“•” 输出却是"?"。
windows 中 BSTR 就是 w_char ;