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 使用为例,记录交叉编 ...
随机推荐
- Netcore logging config
- [leetcode-667-Beautiful Arrangement II]
Given two integers n and k, you need to construct a list which contains n different positive integer ...
- php分页类的实现与调用 (自我摘记)
page.class.php <?php namespace Component; class Page { private $total; //数据表中总记录数 private $listRo ...
- Java之comparable接口
comparable 接口: 1. 问题:java.util.Collections 类中的方法 Collections.sort(List list) 是根据什么确定容器中对象的“大小”顺序的? 2 ...
- PagedDataSource数据绑定控件和AspNetPager分页控件结合使用列表分页
1.引用AspNetPager.dll. 2.放置Repeater数据绑定控件. <asp:Repeater ID="Repeater1" runat="serve ...
- fuck the browser mode
使用了source insight 4有一段时间了,今天用着突然发现我的鼠标移动到变量.函数.自定义的类型上时,单击鼠标左键直接就跳到了定义处,很像是按住了Ctrl再单击鼠标,用得极其不舒服,开始怀疑 ...
- PokeCats开发者日志(十四)——终章
已经不知道离PokeCats游戏开始开发有多少个晚上了,今晚心血来潮整理随笔的时候发现这个故事还没有划上句号. 故事的结局是最终我拿到了软著权,但是没办法上架到任何一个知名的安卓app市场,连 ...
- mysql 时区问题:The server time zone value '???ú±ê×??±??' is unrecognized
org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.sql.SQLE ...
- dubbo+zk+maven的那点事
1.服务端建议使用xml方式进行服务暴露,可读性更高: 2.消费端不能直接引入service模块,而是通过引入service-api模块来使用服务端的服务,因为这不是单体应用: 题外话:dubbo是一 ...
- matlab imwrite
函数功能:将图像数据写入到图像文件中,存储在磁盘上. 调用格式:imwrite(A,filename,fmt) A是图像数据,filename是目标图像名字,fmt是要生成的图片的格式. 图片格式有: ...