在cocos2dx中使用iconv库解决中文乱码问题

发表于2018-05-10
评论0 3.6k浏览
本篇文章主要告诉大家解决在cocos2dx中使用iconv库解决中文乱码问题的方法, iconv的作用是将文本在多种国际编码格式之间进行转换。

头文件"iconv.h"。iconv命令可以将一种已知的字符集文件转换成另一种已知的字符集文件。

目前版本为2.3.26,支持的内码包括:Unicode相关编码,如UTF-8、UTF-16等等,各国采用的ANSI编码,其中包括GB2312、BIG5等中文编码方式。

作为编程接口的iconv包括3个函数:
  1. iconv_open函数用于初始化用于转换的内部缓冲区,指明需要从何种编码方式转换到哪一种。
  2. iconv函数进行实际的转换,需要给出两个间接缓冲区指针和剩余字节数指针。该函数需要更新所有相关信息,因此将不可改写的指针传递给iconv是错误的。
  3. iconv_close函数释放iconv_open函数的缓冲区。

Convert.h
#ifndef _Convert_H_  
#define _Convert_H_  
#include <vector>  
#include <string>  
namespace utility  
{  
    int utf8_len(std::string utf8);  
    std::string a_u8(std::string gbk);  
    std::string u8_a(std::string utf8);  
}   
#endif // _Convert_H_  

Convert.cpp
#include "Convert.h"  
#include "cocos2d.h"  
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)  
#include "win32-specific\icon\include\iconv.h"  
//#pragma comment(lib,"libiconv.lib")  
#else  
#include <iconv.h>  
#endif  
//////////////////////////////////////////////////////////////////////////  
/** 
 * 计算utf8字符串长度 
 * @param utf8 utf8字符串  
 * @return 字符串长度 
 */  
int utf8_len(const char *utf8)   
{  
    int i = 0, j = 0;  
    while (utf8[i]) {  
        if ((utf8[i] & 0xc0) != 0x80) j++;  
        i++;  
    }  
    return j;  
}  
int utf8_cmp(const char* str1, const char* str2)  
{  
    unsigned int len1=(unsigned int)strlen((char*)str1);     
    unsigned int len2=(unsigned int)strlen((char*)str2);     
    unsigned int len = (len1<len2) ? len1 : len2;     
    int ret = memcmp(str1,str2,len);     
    if(ret == 0){     
        if(len1 > len2) ret = 1;     
        else if(len1 < len2) ret = -1;     
    }     
    return ret;     
}  
/** 
 * 计算ucs2字符串长度 
 * @param ucs2 ucs2字符串  
 * @return 字符串长度 
 */  
int ucs2_len(const unsigned short* ucs2)  
{  
    int i = 0;  
    while (ucs2[i] != 0)  
    {  
        char c0 = ucs2[i]&0xff;  
        char c1 = ucs2[i]>>8&0xff;  
        if (c0 == '\0' && c1 == '\0')  
            break;  
        ++i;  
    }  
    return i;  
}  
/////////////////////////////////////////////////////////////////////////////  
int code_convert(const char *from_charset, const char *to_charset, const char *inbuf, size_t inlen, char *outbuf, size_t outlen)  
{      
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)  
    iconv_t cd;  
    const char *temp = inbuf;  
    const char **pin = &temp;  
    char **pout = &outbuf;  
    memset(outbuf,0,outlen);  
    cd = iconv_open(to_charset,from_charset);  
    if(cd==0) return -1;  
    if(-1==iconv(cd,pin,&inlen,pout,&outlen)) return -1;  
    iconv_close(cd);  
    return 0;  
#endif  
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)  
    iconv_t cd;  
    const char *temp = inbuf;  
    const char **pin = &temp;  
    char **pout = &outbuf;  
    memset(outbuf,0,outlen);  
    cd = iconv_open(to_charset,from_charset);  
    if(cd==0) return -1;  
    if(-1==iconv(cd, (char **)(pin),&inlen,pout,&outlen)) return -1;  
    iconv_close(cd);  
    return 0;  
#endif  
    return 0;  
}  
namespace utility  
{  
    /** 
     * 计算utf8字符串长度 
     * @param utf8 utf8字符串  
     * @return 字符串长度 
     */  
    int utf8_len(std::string utf8)   
    {  
        return strlen(utf8.c_str());  
    }  
    int IsTextUTF8(const char* str,unsigned int  length)    
    {    
        return 0;  
        unsigned int i;    
        unsigned long nBytes=0;//UFT8可用1-6个字节编码,ASCII用一个字节    
        unsigned char chr;    
        int bAllAscii=1; //如果全部都是ASCII, 说明不是UTF-8    
        for(i=0;i<length;i++)    
        {    
            chr= *(str+i);    
            if( (chr&0x80) != 0 ) // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx    
                bAllAscii= 0;    
            if(nBytes==0) //如果不是ASCII码,应该是多字节符,计算字节数    
            {    
                if(chr>=0x80)    
                {    
                    if(chr>=0xFC&&chr<=0xFD)    
                        nBytes=6;    
                    else if(chr>=0xF8)    
                        nBytes=5;    
                    else if(chr>=0xF0)    
                        nBytes=4;    
                    else if(chr>=0xE0)    
                        nBytes=3;    
                    else if(chr>=0xC0)    
                        nBytes=2;    
                    else    
                    {    
                        return 0;    
                    }    
                    nBytes--;    
                }    
            }    
            else //多字节符的非首字节,应为 10xxxxxx    
            {    
                if( (chr&0xC0) != 0x80 )    
                {    
                    return 0;    
                }    
                nBytes--;    
            }    
        }    
        if( nBytes > 0 ) //违返规则    
        {    
            return 0;    
        }    
        if( bAllAscii ) //如果全部都是ASCII, 说明不是UTF-8    
        {    
            return 0;    
        }    
        return 1;    
    }  
    std::string a_u8(std::string gbk)  
    {  
        size_t inlen = strlen(gbk.c_str());  
        if (inlen <= 0)  
        {  
            return std::string();  
        }  
        char * outbuf = new char[inlen * 4+2];  
        std::string strRet = gbk;  
        if(code_convert("gbk", "utf-8", gbk.c_str(), inlen, outbuf, inlen * 4+2 ) == 0)  
        {  
            strRet = outbuf;  
        }  
        delete [] outbuf;  
        return strRet;  
    }  
    std::string u8_a(std::string utf8)  
    {  
        size_t inlen = strlen(utf8.c_str());  
        if (inlen <= 0)  
        {  
            return "";  
        }  
        char * outbuf = new char[inlen * 4+2];  
        std::string strRet = utf8;  
        if(code_convert("utf-8", "gbk", utf8.c_str(), inlen, outbuf, inlen*4+2) == 0)  
        {  
            strRet = outbuf;  
        }  
        else  
        {  
            strRet = "Error";  
        }  
        delete [] outbuf;  
        return strRet;  
    }  
}   

Mac下系统自带iconv.h文件

NDK自带的iconv,查看 android-ndk-r9d/sources/android/support/include/iconv.h
在Android.mk中加入
LOCAL_WHOLE_STATIC_LIBRARIES += android_support
$(call import-module,android/support)

编译android包,cocos compile -p android,就不会报iconv.h文件找不到的问题了。
来自:https://blog.csdn.net/shimazhuge/article/details/71681914

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引