zoukankan      html  css  js  c++  java
  • 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+1)*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((2*len+1)*sizeof(char));
    
        Unicode2MBCS(b,wstr.c_str());
    
        string r(b);
    
        free(b);
    
        return r;
    
    }
    
     
    
    int wputs(wstring wstr)
    
    {
    
        wputs(wstr.c_str());
    
        return 0;
    
    }
    
     
    
    int wputs(const wchar_t * wstr)
    
    {
    
        int len = wcslen(wstr);
    
        char * buff = (char *)malloc((len * 2 + 1)*sizeof(char));
    
        Unicode2MBCS(buff,wstr);
    
        printf("%s",buff);
    
        free(buff);
    
        return 0;
    
    }

     =============================================

    (另外大家关心的UTF8如何转换,添加一段转自End2012的UTF8--Unicode转换程序)

    wchar_t * UTF8ToUnicode( const char* str )
    {
        int textlen ;
        wchar_t * result;
        textlen = MultiByteToWideChar( CP_UTF8, 0, str,-1, NULL,0 ); 
        result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t)); 
        memset(result,0,(textlen+1)*sizeof(wchar_t)); 
        MultiByteToWideChar(CP_UTF8, 0,str,-1,(LPWSTR)result,textlen ); 
        return result; 
    }
    char * UnicodeToUTF8( const wchar_t* str )
    {
        char* result;
        int textlen;
        textlen = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
        result =(char *)malloc((textlen+1)*sizeof(char));
        memset(result, 0, sizeof(char) * ( textlen + 1 ) );
        WideCharToMultiByte( CP_UTF8, 0, str, -1, result, textlen, NULL, NULL );
        return result;
    }
  • 相关阅读:
    牛客小白月赛16E
    洛谷P1309 瑞士轮
    洛谷P1781 宇宙总统
    洛谷P1068 分数线划定
    洛谷P1059 明明的随机数(桶排思想)
    洛谷P1177 【模板】快速排序 (归并排序)
    Python基础-----sys模块
    Python基础-----模块导入注意事项
    Python基础-----os模块
    Python基础-----random随机模块(验证码)
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/3665545.html
Copyright © 2011-2022 走看看