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 使用为例,记录交叉编 ...
随机推荐
- Jedis 与 MySQL的连接线程安全问题
Jedis的连接是非线程安全的 下面是set命令的执行过程,简单分为两个过程,客户端向服务端发送数据,服务端向客户端返回数据,从下面的代码来看:从建立连接到执行命令是没有进行任何并发同步的控制 pub ...
- php面试的那些“黑话”
以下是一些常见的面试暗语,求职者一定要弄清楚其中蕴含的深意,不然可能“躺着也中枪”,最后只能铩羽而归. (1)请把简历先放在这,有消息我们会通知你的 面试官说出这句话,则表明他对你已经“兴趣不大”,为 ...
- Python3 数据类型-集合
在Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 集合 ...
- 最多水容器(M)
题目 给定n个非负整数a 1,a 2,...,a n,其中每个代表坐标(i,a i)处的一个点.绘制n条垂直线,使得线i的两个端点处于(i,a i)和(i,0)处.找到两条线,它们与x轴一起形成一个容 ...
- 搭建github
http://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html
- Sparsity Invariant CNNs
文章链接 Abstract 本文研究稀疏输入下的卷积神经网络,并将其应用于稀疏的激光扫描数据的深度信息完成实验.首先,我们表明,即使当丢失数据的位置提供给网络时,传统卷积网络在应用于稀疏数据时性能也很 ...
- lintcode-143-排颜色 II
143-排颜色 II 给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序. 注意事项 You are not ...
- 数据库集群之路二 MYCAT
windows下安装配置并使用mycat 参考:http://www.cnblogs.com/parryyang/p/5758087.html 一 下载windows版本 https://github ...
- thinkphp5 隐藏入口和支持pathinfo
url里public目录的隐藏 其实正常思路的话这个url里的public本身就是不存在的,然后呢,其实也不叫隐藏public目录,这里只是考虑到有些童鞋可能还会按之前3.x时代的习惯来配置网站根目录 ...
- scala中的模式匹配
基本语法 变量 match { case 值1 => 代码 case 值2 => 代码 ... case 值N if (...) => 代码 case _ => 代码 } 常量 ...