(1) 首先包含iconv.h头文件,c++->常规->附加包含目录:cocos2dx\platform\third_party\win32\iconv,如图:
(2) 创建头文件IconvString.h,源码:
#ifndef ICONV_STRING_H #define ICONV_STRING_H int convert(char *from_charset, char *to_charset, char *inbuf, size_t inlen, char *outbuf, size_t outlen); int gbk2utf8(char *inbuf, size_t inlen, char *outbuf, size_t outlen); #endif
#include <string> #include "iconv.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) // 编译链接的时候指定静态库 #pragma comment(lib,"libiconv.lib") #endif int convert(char *from_charset, char *to_charset, char *inbuf, size_t inlen, char *outbuf, size_t outlen) { iconv_t iconvH; iconvH = iconv_open(to_charset, from_charset); if( !iconvH ) return NULL; memset(outbuf, 0, outlen); #if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) const char *temp = inbuf; const char **pin = &temp; char **pout = &outbuf; if( !iconv(iconvH, pin, &inlen, pout, &outlen) ) { iconv_close(iconvH); return NULL; } #else if( !iconv(iconvH, &inbuf, &inlen, &outbuf, &outlen) ) { iconv_close(iconvH); return NULL; } #endif iconv_close(iconvH); return NULL; } int gbk2utf8(char *inbuf, size_t inlen, char *outbuf, size_t outlen) { return convert("gb2312", "utf-8", inbuf, inlen, outbuf, outlen); }
LOCAL_PATH:= $(call my-dir) #libiconv.so include $(CLEAR_VARS) LOCAL_MODULE := libiconv LOCAL_CFLAGS := \ -Wno-multichar \ -DAndroid \ -DLIBDIR="c" \ -DBUILDING_LIBICONV \ -DIN_LIBRARY LOCAL_SRC_FILES := \ libcharset/lib/localcharset.c \ lib/iconv.c \ lib/relocatable.c LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/include \ $(LOCAL_PATH)/libcharset \ $(LOCAL_PATH)/lib \ $(LOCAL_PATH)/libcharset/include \ $(LOCAL_PATH)/srclib include $(BUILD_STATIC_LIBRARY)
char *inBuf = "iconv: 你好,Alex Zhou"; size_t inLen = strlen(inBuf); size_t outLen = inLen << 1; char *outBuf = (char *)malloc(outLen); gbk2utf8(inBuf, inLen, outBuf, outLen); CCLabelTTF* pLabel = CCLabelTTF::create(outBuf, "Arial", 30); pLabel->setColor(ccBLACK); free(outBuf);要注意转码前后的字符串占的空间是不一样的, 需要知道每种编码格式字符占的字节数:我的vs选择的是Unicode字符集,所以中文字符占2个字节,英文字符占1个字节;gb2312每个字符占2个字节,而UTF-8中文字符占3个字节,英文字符占1个字节。所以这里把存储输出的字符串的数组容量扩大了一部。
2. 使用xml的方式
这里使用了引擎提供的CCSAXParser来解析xml,它内部是用libxml2来实现的。
(1) 创建XmlParser.h文件,源码:
#ifndef XML_PARSE_H #define XML_PARSE_H #include <string> #include "cocos2d.h" class XMLParser : public cocos2d::CCObject, public cocos2d::CCSAXDelegator { public: static XMLParser* parseWithFile(const char *xmlFileName); static XMLParser* parseWithString(const char *content); XMLParser(); virtual ~XMLParser(); // 从本地xml文件读取 bool initWithFile(const char *xmlFileName); // 从字符中读取,可用于读取网络中的xml数据 bool initWithString(const char *content); /** *对应xml标签开始,如:<string name="alex">, name为string,atts为string的属性,如["name","alex"] */ virtual void startElement(void *ctx, const char *name, const char **atts); /** *对应xml标签结束,如:</string> */ virtual void endElement(void *ctx, const char *name); /** *对应xml标签文本,如:<string name="alex">Alex Zhou</string>的Alex Zhou */ virtual void textHandler(void *ctx, const char *s, int len); cocos2d::CCString* getString(const char *key); private: cocos2d::CCDictionary *m_pDictionary; std::string m_key; std::string startXMLElement; std::string endXMLElement; }; #endif
#include "XMLParser.h" using namespace std; using namespace cocos2d; // 空格 const static int SPACE = 32; // 换行 const static int NEXTLINE = 10; // tab 横向制表符 const static int TAB = 9; XMLParser* XMLParser::parseWithFile(const char *xmlFileName) { XMLParser *pXMLParser = new XMLParser(); if( pXMLParser->initWithFile(xmlFileName) ) { pXMLParser->autorelease(); return pXMLParser; } CC_SAFE_DELETE(pXMLParser); return NULL; } bool XMLParser::initWithFile(const char *xmlFileName) { m_pDictionary = new CCDictionary(); CCSAXParser _parser; _parser.setDelegator(this); const char *fullPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(xmlFileName); return _parser.parse(fullPath); } XMLParser* XMLParser::parseWithString(const char *content) { XMLParser *pXMLParser = new XMLParser(); if( pXMLParser->initWithString(content) ) { pXMLParser->autorelease(); return pXMLParser; } CC_SAFE_DELETE(pXMLParser); return NULL; } bool XMLParser::initWithString(const char *content) { m_pDictionary = new CCDictionary(); CCSAXParser _parse; _parse.setDelegator(this); return _parse.parse(content, strlen(content) ); } void XMLParser::startElement(void *ctx, const char *name, const char **atts) { this->startXMLElement = (char *)name; CCLog("start=%s", startXMLElement.c_str()); if(this->startXMLElement == "string") { while(atts && *atts) { const char *attsKey = *atts; if(0 == strcmp(attsKey, "name")) { ++ atts; const char *attsValue = *atts; m_key = attsValue; break; } ++ atts; } } } void XMLParser::endElement(void *ctx, const char *name) { this->endXMLElement = (char *)name; CCLog("end=%s", endXMLElement.c_str()); } void XMLParser::textHandler(void *ctx, const char *s, int len) { string value((char *)s, 0, len); //是否全是非正常字符 bool noValue = true; for(int i = 0; i < len; ++i) { if(s[i] != SPACE && s[i] != NEXTLINE && s[i] != TAB) { noValue = false; break; } } if(noValue) return; CCString *pString = CCString::create(value); CCLog("key=%s value=%s", m_key.c_str(), pString->getCString()); this->m_pDictionary->setObject(pString, this->m_key); } CCString* XMLParser::getString(const char *key) { string strKey(key); return (CCString *)this->m_pDictionary->objectForKey(strKey); } XMLParser::XMLParser() { } XMLParser::~XMLParser() { CC_SAFE_DELETE(this->m_pDictionary); }
<string name="a">b</string>
XMLParser *pXmlParser = XMLParser::parseWithFile("strings.xml"); CCString *pValue1 = pXmlParser->getString("hello"); CCString *pValue2 = pXmlParser->getString("name"); CCString *pValue = CCString::createWithFormat("%s%s%s%s", "XML: ", pValue1->getCString(), ",", pValue2->getCString()); CCLabelTTF* pLabel = CCLabelTTF::create(pValue->getCString(), "Arial", 30); pLabel->setColor(ccBLACK);
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">你好</string> <string name="name">Alex Zhou</string> </resources>
ok,到这里就结束了,android对应的iconv库我已经打包到源码中了。
源码:http://download.csdn.net/detail/zhoujianghai/5031137
转载请注明来自:Alex Zhou的程序世界,本文链接:http://codingnow.cn/cocos2d-x/1038.html