转自: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. js match regex

    需要返回成数组元素的要放在括号里头 var arr = /input-([0-9]*)-([0-9]*)/.exec(id); var all = arr[0]; var row = arr[1]; ...

  2. ueditor-百度编辑器插件

    1.官网地址:http://ueditor.baidu.com/website/index.html 2.定制化工具栏:(1)修改ueditor.config.js的toolsbar(2)在创建编辑器 ...

  3. PHP如何返回json格式的数据

    我们常见一些网站在做ajax时返回JSON格式的数据: 返回的是json格式的数据 这有什么好处那?很显然前端在接到返回的数据时可以直接使用,而不用再用eval('(+ returnString +) ...

  4. Ajax轮询以及Comet模式—写在Servlet 3.0发布之前(转)

    2008 年的夏天,偶然在网上闲逛的时候发现了 Comet 技术,人云亦云间,姑且认为它是由 Dojo 的 Alex Russell 在 2006 年提出.在阅读了大量的资料后,萌发出写篇 blog ...

  5. c++中实现委托

    成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(clo ...

  6. 组建自动化工具Ant

    组建自动化工具Ant Ant可以帮助我们自动化的完成项目的构建 下面是维基百科对Ant的介绍:http://zh.wikipedia.org/wiki/Apache_Ant Apache Ant,是一 ...

  7. (转载)高速ADC的关键指标:量化误差、offset/gain error、DNL、INL、ENOB、分辨率、RMS、SFDR、THD、SINAD、dBFS、TWO-TONE IMD

    (一)一个基本概念 分贝(dB):按照对数定义的一个幅度单位.对于电压值,dB以20log(VA/VB)给出:对于功率值,以10log(PA/PB)给出.dBc是相对于一个载波信号的dB值:dBm是相 ...

  8. HTTP Post请求过程详解

    摘要: HTTP(HyperText Transfer Protocol),超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP),客户端是终端用户,服务器端是网站. HTTP是基于Sock ...

  9. 【转】 Linux Shell 命令--rename

    重命名文件,经常用到mv命令,批量重命名文件rename是最好的选择,Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,判断方法:输入man rename 看到第 ...

  10. Determining IP information for eth0... failed; no link present. Check cable?

    在RedHat下重启网络,service network restart之后,出现问题 Determining IP information for eth0... failed; no link p ...