转自: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++ 中文字符串处理方法的更多相关文章

  1. IDA pro 6.8显示中文字符串的方法

    IDA pro 6.8设置显示中文字符串的方法 M4x原创,转载请表明出处http://www.cnblogs.com/WangAoBo/p/7636335.html IDA是一款强大无比的反编译软件 ...

  2. thinkphp模板中截取中文字符串的方法分享

    前段用thinkphp写了一个系统,感觉thinkphp学起来比较容易,开发起来了比较顺手,其中一个关键的因素就是它的模版引擎相当强大,使用方法跟smarty类似,在模版中还可以用php代码,有模版包 ...

  3. PHP截取中文字符串方法总结

    <?php @header('Content-type: text/html; charset=UTF-8'); $arr = "sa撒的发dfa多少sfd看sdf得12上24飞452 ...

  4. php截取中文字符串,英文字符串,中英文字符串长度的方法

    今天学习了php函数截取中文字符串,英文字符串,中英文字符串的函数使用方法.对中英文截取方法不理解,此处先做记录. PHP自带的函数如strlen().mb_strlen()都是通过计算字符串所占字节 ...

  5. PHP截取中文字符串不出现?号的解决方法[原创]

    PHP截取中文字符串不出现?号的解决方法[原创] 大 | 中 | 小 [不指定 -- : | by 张宴 ] [文章作者:张宴 本文版本:v1. 最后修改: 转载请注明出处:http://blog.z ...

  6. php 截取中文字符串方法

    /** * 截取中文字符串函数 * @param $str 需要截取的字串 * @param $start 开始截取的位置 * @param $length 截取的长度 * @return 此函数返回 ...

  7. 解决Spring MVC @ResponseBody返回中文字符串乱码问题

    spring mvc使用的默认处理字符串编码为ISO-8859-1 解决方法: 第一种方法: 对于需要返回字符串的方法添加注解,如下: @RequestMapping(value="/use ...

  8. js jQuery中文字符串比较

    先说下普通字符串(英文)比较: 一般使用双等来判断(==),如果还需要类型相同那么就用三等(===) 1. 双等(==)是完全向后兼容的,如果两个操作数类型不一致,它会在某些时候自动对操作数进行类型转 ...

  9. PHP json_encode中文乱码解决方法

    相信很多人在使用Ajax与后台php页面进行交互的时候都碰到过中文乱码的问题.JSON作为一种轻量级的数据交换格式,备受亲睐,但是用PHP作为后台交互,容易出现中文乱码的问题.JSON和js一样,对于 ...

随机推荐

  1. 可以Ping通和DNS解析,但打不开网页的解决办法

    一. 网络故障表现为: 1.Ping地址正常,能ping通任何本来就可以ping通地址,如网关.域名. 2.能DNS解析域名. 3.无法打开网页,感觉是网页打开的一瞬间就显示无网络连接. 4.只需要连 ...

  2. Karel运行环境配置

    1.下载 见http://wenku.baidu.com/view/24762ced998fcc22bcd10d5e.html 2.界面空白问题 问题:运行Karel后,发现整个界面空白一片,没有任何 ...

  3. Android配置时,点击eclipse里Window->Preferences里的android选项出错

    An error has occurred when creating this preference page. 解决方法:重起eclipse

  4. jvm调优之四:生产环境参数实例及分析【生产环境实例增加中】

    java application项目(非web项目) 改进前: -Xms128m-Xmx128m-XX:NewSize=64m-XX:PermSize=64m-XX:+UseConcMarkSweep ...

  5. HDU5828 Rikka with Sequence 线段树

    分析:这个题和bc round 73应该是差不多的题,当时是zimpha巨出的,那个是取phi,这个是开根 吐槽:赛场上写的时候直接维护数值相同的区间,然后1A,结果赛后糖教一组数据给hack了,仰慕 ...

  6. OpenGl从零开始之坐标变换(上)

    坐标变换是深入理解三维世界的基础,非常重要.学习这部分首先要清楚几个概念:视点变换.模型变换.投影变换.视口变换. 在现实世界中,所有的物体都具有三维特征,但计算机本身只能处理数字,显示二维的图形,因 ...

  7. NSIS学习笔记(转)

    转自:http://blog.csdn.net/lee353086/article/details/45919901 NSIS学习笔记Date:2015-05-20Author:kagulaEnv:V ...

  8. C++设计模式——单例模式

    问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进 ...

  9. WCF配置文件全攻略

    參考:http://www.cnblogs.com/wayfarer/archive/2007/08/24/867987.html http://www.cnblogs.com/scy251147/a ...

  10. Unable to find vcvarsall.bat解决方法

    今天在安装scikit-learn时出现了 error: Unable to find vcvarsall.bat 在安装一些Python模块时,大部分是cpython写的模块时会发生如下错误 err ...