std::string在多字节字符集环境下substr的实现方法
昨天写到《使用多字节字符集的跨平台(PC、Android、IOS、WP)编码/解码方法》中提到服务端使用std::string处理字符串,std::string对多字节字符集支持并不是很完善,std::string中的函数没有对多字节字符集进行直接的支持。
例如直接调用std::string的substr函数,就会导致某些情况下截取的字符串尾部产生非法字符。
GB系列多字节字符集基础知识:
VC环境下工程设置为多字节字符集,默认使用的是GBK编码,GB2312、GBK、GB18030,这3个都是中文编码方式,并向下兼容。
1、GB2312包含7000多个汉字和字符,GBK包含21000多个,GB18030包含27000多个。
2、GBK中的中文字符是双字节来表示的,英文字符是用ASCII码表示的,也就是单字节表示的。
3、GBK编码表中也有英文字符的双字节表示形式,所以英文字母可以有2中GBK表示方式。
4、GBK编码中的中文字符将其最高位都定成1,英文字符单字节最高位都为0。
5、当用GBK解码时,若高字节最高位为0,则用ASCII码表解码;若高字节最高位为1,则用GBK编码表解码。
以上5点就可以解释了std::string中substr为什么会在尾部产生非法字符的问题了,substr只考虑了字节长度,没考虑多字节字符集编码。
对于使用substr截断的字符串,在IOS环境下使用NSString初始化时会失败,而Android的String类型则会容忍非法字符。
为了彻底解决平台兼容性问题,必须自己实现截取函数:
int GbkSubString(const char *s, int iLeft)
{
int len = 0, i = 0; if( s == NULL || *s == 0 || iLeft <= 0 )
return(0); while( *s )
{
if( (*s & 0x80) == 0 )
{
i ++;
s ++;
len ++;
}
else
{
if( *(s + 1) == 0 ) break; i += 2;
s += 2;
len += 2;
} if( i == iLeft ) break;
else if( i > iLeft )
{
len -= 2;
break;
}
} return(len);
}
先使用GbkSubString函数对长度进行处理,再使用返回的准确长度调用substr。
记录,为更好的自己!
std::string在多字节字符集环境下substr的实现方法的更多相关文章
- Oracle 11g RAC环境下Private IP修改方法及异常处理
Oracle 11g RAC环境下Private IP修改方法及异常处理 Oracle 11g RAC环境下Private IP修改方法及异常处理 一. 修改方法 1. 确认所有节点CRS服务以启动 ...
- PHP环境下Memcache的使用方法
原文:PHP环境下Memcache的使用方法 原文地址:http://www.2cto.com/kf/201503/384967.html 如今互联网崛起的时代,各大网站都面临着一个大数据流问题,怎么 ...
- 分布式环境下的id生成方法
分布式环境下的id生成方法 前几天研究数据库分表分库的问题,其中有一个关键的地方就是生成唯一键的问题,假如数据表有1亿条数据,而且还在不断的增加,这里我们就需要考虑到分表分库,假设我们采用Hash ...
- CDN 环境下获取用户IP方法
CDN 环境下获取用户IP方法 1 cdn 自定义header头的X-Real-IP,在后端使用$http_x_real_ip获得 proxy_set_header X-Real-IP $remote ...
- 转载:一种云环境下SaaS软件部署方法及装置与流程
转载:http://www.xjishu.com/zhuanli/55/201710103925.html 本发明涉及云计算技术领域,特别是涉及一种云环境下SaaS软件部署方法及装置. 背景技术: 随 ...
- Visual Studio2008环境下查找C#中方法的“查看所有引用”
在Visual Studio开发环境下,想必F12我们都很熟悉了,有没有用过“查看所有引用”呢? 尤其是在一个解决方案中,包含了很多项目,彼此相互的调用是很常见的,例如三层架构, BLL调用DAL,D ...
- 分布式环境下Unique ID生成方法
ID即标示符,在某个搜索域内能唯一标示其中某个对象.在关系型数据库中每个表都需要定义一个主键来唯一标示一条记录.为了方便一般都会使用一个auto_increment属性的整形数做为ID.因为数据库本身 ...
- Kubernetes环境下的各种调试方法
作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文介绍在Kubernetes环境下的调试方法,希望对读者有用.如果关 ...
- 交叉编译问题记录-嵌入式环境下 GDB 的使用方法
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10693247.html 本文以嵌入式 Linux 环境下的 gdb 使用为例,记录交叉编 ...
随机推荐
- Java基础知识:Java实现Map集合二级联动3
* Returns an image stored in the file at the specified path * @param path String The path to the ima ...
- CVPR-2018 那些有趣的新想法
Taylor Guo @ Shanghai - 2018.10.18 缘起 还有什么比顶级会议更适合寻找有趣新想法的地方吗?我们从CVPR 2018 计算机视觉和模式识别的顶级会议中发现了很多有趣的东 ...
- (转载)IE8+兼容经验小结
本文分享下我在项目中积累的IE8+兼容性问题的解决方法.根据我的实践经验,如果你在写HTML/CSS时候是按照W3C推荐的方式写的,然后下面的几点都关注过,那么基本上很大一部分IE8+兼容性问题都OK ...
- nodejs笔记--与Redis的交互篇(六)
原文地址:http://www.cnblogs.com/zhongweiv/p/node_redis.html 安装前准备 win64: Install python: http://www.pyth ...
- Thunder团队第三周 - Scrum会议3
Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:代秋彤 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...
- android 出现Make sure the Cursor is initialized correctly before accessing data from it
Make sure the Cursor is initialized correctly before accessing data from it 详细错误是:java.lang.IllegalS ...
- 移动端调试和fiddler移动端抓包使用
这里介绍一款移动端的调试工具以及抓包工具fiddler的使用.也是初次接触,算是初次接触的总结. 1,移动端调试工具.手机截图如下 代码实现 <!DOCTYPE html> <htm ...
- vim 删除文件全部内容
很多时候我们需要删除脚本文件全部内容, 重新再写入新的内容,进行其他的操作: 很多时候我们对应用程序的排错需要查看日志文件,然而日志中通常有许多我们以前的应用程序产生的日志,其他的日志过多的时候,有时 ...
- listBox和pictureBox的使用
重要属性:pictureBox中SizeMode可以更改图像显示的尺寸大小. using System; using System.Collections.Generic; using System. ...
- Android基础------高级ul:消息提示
前言:Android消息提示笔记,刚刚接触Android 1.静态方法Toast 直接调用静态方法 //消息提示(context,"内容",固定时间) Toast.makeText ...