继续上篇的问题。
在解决了中文显示乱码的问题之后,仍然有很多的问题需要我们解决。
现在放在我们面前的问题有2个。第一个是虽然可以显示中文,但是是wstring的类型,肯定不是我们经常使用的数据类型,所以最好有一个熟悉的数据类型string来替换;
第二个是编码问题,ios 和 android都是支持unicode编码的,而gbk只有在VS2010 的时候才使用。
第一个问题,需要string 转换成wstring ,wstring 转换成 gbk编码的string数据类型。
使用setlocal() 需要引入头文件
#include <locale>
函数模块stringToWstring:
//将string转换成wstrin wstring UTF8ToGBK::stringToWstring(const string str) { setlocale(LC_ALL, "chs"); const char* _Source = str.c_str(); size_t _Dsize = str.size() + 1; wchar_t *_Dest = new wchar_t[_Dsize]; wmemset(_Dest, 0, _Dsize); mbstowcs(_Dest,_Source,_Dsize); std::wstring result = _Dest; delete []_Dest; setlocale(LC_ALL, "C"); return result; }
这里面有几个库函数可能大家比较陌生,可以深入学习,也可以浅尝即止。
这里要说下,学习技术的一点建议。技术,是不可能全部掌握的。尤其是在现在的知识大爆炸时代。知识的增长都是数量级的。当然如果有大量的时间,可以去做学术类的研究。如果是以产品为重,就不要花费更多的时间浪费在其他的技术上面。而更应该专注自己的技术和产品。程序员很多时候会有点盲目的追求技术,而忘记自己的 更重要的职责。
上面的几个库函数的简单介绍:
**********************************************
**************************************************************************
******************************************************
好的简单的介绍之后,来解决第二个问题。
宏定义。
这里提供两个宏定义。一个是Windows自身带的宏,一个是cocos2d-X为我们提供的。
先看第一个宏。
#ifdef WIN32 printf("这是Windows 平台\n");//执行的代码模块放在这里 #endif
/* * Define WIN32 when build target is Win32 API */ #if (defined(_WIN32) || defined(__WIN32__)) && \ !defined(WIN32) && !defined(__SYMBIAN32__) #define WIN32 #endif
在看cocos2d—X为我们封装的宏。
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) //执行代码的模块 #endif
下面可以看到所有有关平台定义的宏。
#ifndef __CC_PLATFORM_CONFIG_H__ #define __CC_PLATFORM_CONFIG_H__ /** Config of cocos2d-x project, per target platform. */ ////////////////////////////////////////////////////////////////////////// // pre configure ////////////////////////////////////////////////////////////////////////// // define supported target platform macro which CC uses. #define CC_PLATFORM_UNKNOWN 0 #define CC_PLATFORM_IOS 1 #define CC_PLATFORM_ANDROID 2 #define CC_PLATFORM_WIN32 3 #define CC_PLATFORM_MARMALADE 4 #define CC_PLATFORM_LINUX 5 #define CC_PLATFORM_BADA 6 #define CC_PLATFORM_BLACKBERRY 7 #define CC_PLATFORM_MAC 8 #define CC_PLATFORM_NACL 9 #define CC_PLATFORM_EMSCRIPTEN 10 #define CC_PLATFORM_TIZEN 11 // Determine target platform by compile environment macro. #define CC_TARGET_PLATFORM CC_PLATFORM_UNKNOWN // mac #if defined(CC_TARGET_OS_MAC) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_MAC #endif // iphone #if defined(CC_TARGET_OS_IPHONE) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_IOS #endif // android #if defined(ANDROID) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_ANDROID #endif // win32 #if defined(WIN32) && defined(_WINDOWS) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_WIN32 #endif // linux #if defined(LINUX) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_LINUX #endif // marmalade #if defined(MARMALADE) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_MARMALADE #endif // bada #if defined(SHP) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_BADA #endif // qnx #if defined(__QNX__) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_BLACKBERRY #endif // native client #if defined(__native_client__) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_NACL #endif // Emscripten #if defined(EMSCRIPTEN) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_EMSCRIPTEN #endif // tizen #if defined(TIZEN) #undef CC_TARGET_PLATFORM #define CC_TARGET_PLATFORM CC_PLATFORM_TIZEN #endif ////////////////////////////////////////////////////////////////////////// // post configure ////////////////////////////////////////////////////////////////////////// // check user set platform #if ! CC_TARGET_PLATFORM #error "Cannot recognize the target platform; are you targeting an unsupported platform?" #endif #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #pragma warning (disable:4127) #endif // CC_PLATFORM_WIN32 #endif // __CC_PLATFORM_CONFIG_H__
好的,所有问题解决,贴上完整的类:
头文件:
#pragma once #include <iostream> #include <stdio.h> //string是c++ 的头文件,其内包含了一个string类,string s1就是建立一个string类的对象 #include <string> //cstring.h 是对应于旧C 头文件的std 版本 #include <cstringt.h> #include <locale> #define LOGNEWLINE printf("\n") using namespace std; class UTF8ToGBK { public: UTF8ToGBK(void); ~UTF8ToGBK(void); //将unicode编码的string转换成wstring static wstring stringToWstring(const string text); //将utf8格式编码转化成gbk,vs2010的默认的编码格式 static string UTF8TOGBK(const string text); };
.CPP文件:
#include "UTF8ToGBK.h" UTF8ToGBK::UTF8ToGBK(void) { } UTF8ToGBK::~UTF8ToGBK(void) { } //将string转换成wstring wstring UTF8ToGBK::stringToWstring(const string str) { setlocale(LC_ALL, "chs"); const char* _Source = str.c_str(); size_t _Dsize = str.size() + 1; wchar_t *_Dest = new wchar_t[_Dsize]; wmemset(_Dest, 0, _Dsize); mbstowcs(_Dest,_Source,_Dsize); std::wstring result = _Dest; delete []_Dest; setlocale(LC_ALL, "C"); return result; } //当在WIN32 平台下,将utf8格式编码转化成gbk,vs2010的默认的编码格式 string UTF8ToGBK::UTF8TOGBK(const string text) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) wstring tes = stringToWstring(text); int asciSize = WideCharToMultiByte(CP_UTF8,0,tes.c_str(),tes.size(),NULL,0,NULL,NULL); if (asciSize == ERROR_NO_UNICODE_TRANSLATION || asciSize == 0) { return string(); } char *resultString = new char[asciSize]; int conveResult = WideCharToMultiByte(CP_UTF8,0,tes.c_str(),tes.size(),resultString,asciSize,NULL,NULL); if (conveResult != asciSize) { return string(); } string buffer = ""; buffer.append(resultString,asciSize); delete[] resultString; return buffer; #endif return text; }
测试代码如下:
//测试string转换成wstring ,wstring转成string之gbk编码 string test4 = "我们是害虫,我们是害虫,我们很快乐"; string testString = UTF8ToGBK::UTF8TOGBK(test4); CCLog("cclog: testString2: %s",testString.c_str()); printf("printf: testString2: %s",testString.c_str());LOGNEWLINE; CCLabelTTF *testLabel = CCLabelTTF::create(testString.c_str(),"Zapfino",30); testLabel->setPosition(ccp(visibleSize.width*0.5,visibleSize.height*0.2)); testLabel->setColor(ccc3(200,200,200)); this->addChild(testLabel,1);
结果贴图: