c++ 中文字符串处理方法
转自:http://hi.baidu.com/hehehehello/item/dcc44a4a6afc690e6dc2f08b
C++处理中文的问题困扰我很久了。之前一旦遇到中文基本就投诸java怀抱了。
今天看到一个漂亮的c++程序,遂豁然开朗。总结一下分享给大家:
问题描述:
c++ 中 char*/string 形式的字符串无法正确的对中文字符串进行处理(如 find, strlen, substr 等常规操作) 。
比如当你在char* 中 find 英文逗号时,有可能匹配的不只是逗号,还找到了某个汉字的一个字节,而你无法在char*中区分它们。
问题原因:
中文字符长度不固定,按字节处理往往出现乱码或错误分割。在unicode中每个中文为2个字节,而中文中间夹杂的英文和半角标点则仍然是1个字节。
解决方案:
构造三层逻辑结构:输入层、逻辑处理层、输出层。
-- 输入层接收char*输入,并将其转换为wchar*.
-- 逻辑处理层在 wchar* 或 wstring 的基础上进行字符串操作,此时操作最小单位为中文字符,不会再有乱码。
-- 输出层将wchar*的结果再次转换为char* ,返回给外部。
这样,对外部来说,仍然是输入char*, 输出char*, 但在这个过程中不再有分割汉字的操作或乱码。
核心转换代码:
#include<wchar.h>
wchar_t * MBCS2Unicode(wchar_t * buff, const char * str)
{
wchar_t * wp = buff;
char * p = (char *)str;
while(*p)
{
if(*p & 0x80)
{
*wp = *(wchar_t *)p;
p++;
}
else{
*wp = (wchar_t) *p;
}
wp++;
p++;
}
*wp = 0x0000;
return buff;
}
char * Unicode2MBCS(char * buff, const wchar_t * str)
{
wchar_t * wp = (wchar_t *)str;
char * p = buff, * tmp;
while(*wp){
tmp = (char *)wp;
if(*wp & 0xFF00){
*p = *tmp;
p++;tmp++;
*p = *tmp;
p++;
}
else{
*p = *tmp;
p++;
}
wp++;
}
*p = 0x00;
return buff;
}
wstring str2wstr(string str)
{
size_t len = str.size();
wchar_t * b = (wchar_t *)malloc((len+)*sizeof(wchar_t));
MBCS2Unicode(b,str.c_str());
wstring r(b);
free(b);
return r;
}
string wstr2str(wstring wstr)
{
size_t len = wstr.size();
char * b = (char *)malloc((*len+)*sizeof(char));
Unicode2MBCS(b,wstr.c_str());
string r(b);
free(b);
return r;
}
int wputs(wstring wstr)
{
wputs(wstr.c_str());
return ;
}
int wputs(const wchar_t * wstr)
{
int len = wcslen(wstr);
char * buff = (char *)malloc((len * + )*sizeof(char));
Unicode2MBCS(buff,wstr);
printf("%s",buff);
free(buff);
return ;
}
=============================================
(另外大家关心的UTF8如何转换,添加一段转自End2012的UTF8--Unicode转换程序)
wchar_t * UTF8ToUnicode( const char* str )
{
int textlen ;
wchar_t * result;
textlen = MultiByteToWideChar( CP_UTF8, , str,-, NULL, );
result = (wchar_t *)malloc((textlen+)*sizeof(wchar_t));
memset(result,,(textlen+)*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, ,str,-,(LPWSTR)result,textlen );
return result;
}
char * UnicodeToUTF8( const wchar_t* str )
{
char* result;
int textlen;
textlen = WideCharToMultiByte( CP_UTF8, , str, -, NULL, , NULL, NULL );
result =(char *)malloc((textlen+)*sizeof(char));
memset(result, , sizeof(char) * ( textlen + ) );
WideCharToMultiByte( CP_UTF8, , str, -, result, textlen, NULL, NULL );
return result;
}
c++ 中文字符串处理方法的更多相关文章
- IDA pro 6.8显示中文字符串的方法
IDA pro 6.8设置显示中文字符串的方法 M4x原创,转载请表明出处http://www.cnblogs.com/WangAoBo/p/7636335.html IDA是一款强大无比的反编译软件 ...
- thinkphp模板中截取中文字符串的方法分享
前段用thinkphp写了一个系统,感觉thinkphp学起来比较容易,开发起来了比较顺手,其中一个关键的因素就是它的模版引擎相当强大,使用方法跟smarty类似,在模版中还可以用php代码,有模版包 ...
- PHP截取中文字符串方法总结
<?php @header('Content-type: text/html; charset=UTF-8'); $arr = "sa撒的发dfa多少sfd看sdf得12上24飞452 ...
- php截取中文字符串,英文字符串,中英文字符串长度的方法
今天学习了php函数截取中文字符串,英文字符串,中英文字符串的函数使用方法.对中英文截取方法不理解,此处先做记录. PHP自带的函数如strlen().mb_strlen()都是通过计算字符串所占字节 ...
- PHP截取中文字符串不出现?号的解决方法[原创]
PHP截取中文字符串不出现?号的解决方法[原创] 大 | 中 | 小 [不指定 -- : | by 张宴 ] [文章作者:张宴 本文版本:v1. 最后修改: 转载请注明出处:http://blog.z ...
- php 截取中文字符串方法
/** * 截取中文字符串函数 * @param $str 需要截取的字串 * @param $start 开始截取的位置 * @param $length 截取的长度 * @return 此函数返回 ...
- 解决Spring MVC @ResponseBody返回中文字符串乱码问题
spring mvc使用的默认处理字符串编码为ISO-8859-1 解决方法: 第一种方法: 对于需要返回字符串的方法添加注解,如下: @RequestMapping(value="/use ...
- js jQuery中文字符串比较
先说下普通字符串(英文)比较: 一般使用双等来判断(==),如果还需要类型相同那么就用三等(===) 1. 双等(==)是完全向后兼容的,如果两个操作数类型不一致,它会在某些时候自动对操作数进行类型转 ...
- PHP json_encode中文乱码解决方法
相信很多人在使用Ajax与后台php页面进行交互的时候都碰到过中文乱码的问题.JSON作为一种轻量级的数据交换格式,备受亲睐,但是用PHP作为后台交互,容易出现中文乱码的问题.JSON和js一样,对于 ...
随机推荐
- pthread_attr_t 线程属性(一)
1. 线程属性: 使用pthread_attr_t类型表示,我们需要对此结构体进行初始化, 初始化后使用,使用后还要进行去除初始化! ...
- .net core 中的序列化和反序列化
学习博客:http://www.voidcn.com/blog/dujingjing1230/article/p-1204454.html
- the server responded with a status of 404 (Not Found)
1.出现这种问题,第一时间检查文件路径是否正确,相对路径或者绝对路径是否正确 2.某些后缀的文件是否能够找到,我现在碰到的就是.md文件找不到,需要配置web.config <system.we ...
- Android 者开发如何选择测试机列表
Android 系统已经分化成多种不同的定制版本,制造厂商的不同手机使用的硬件千差万别.差异化带来良好的用户体验的同时,也给开发者带来的适配的问题.于是每个开发团队都需要面临选择测试机列表的问题.我基 ...
- VS 2013 EFSQLITE
在 vs 2013 上用 1.NuGet程序包来获取,它也会自动下载EF6的包 :system.Data.sqlite 他会自动下载 其它几个需要的包. 2.在Sqlite官网上下载对应的版本:htt ...
- 写在阿里去IOE一周年
[文/ 任英杰] 去年5月17日,阿里巴巴支付宝最后一台IBM小型机在下线,标志着阿里完成去IOE.随后一场去IOE运动不断发酵,甚至传闻IBM中国去年损失了20%的合同额. 去了IOE,奔向何方?阿 ...
- 【转】Struts2中的MethodFilterInterceptor(转)
这是一个Struts2.1.8.1应用,代码如下 首先是web.xml文件 view plaincopy to clipboardprint?01.<?xml version="1.0 ...
- SQL时间第二期_时间格式化
0 或 100 (*) 默认值 mon dd yyyy hh:miAM(或 PM) 1 101 美国 mm/dd/yyyy ...
- [翻译]创建ASP.NET WebApi RESTful 服务(9)
一旦成功的发布API后,使用者将依赖于你所提供的服务.但是变更总是无法避免的,因此谨慎的制定ASP.NET Web API的版本策略就变得非常重要.一般来说,新的功能需要无缝的接入,有时新老版本需要并 ...
- WebRTC源码分析:音频模块结构分析
一.概要介绍WebRTC的音频处理流程,见下图: webRTC将音频会话抽象为一个通道Channel,譬如A与B进行音频通话,则A需要建立一个Channel与B进行音频数据传输.上图中有三个Chann ...