继续上篇的问题。
在解决了中文显示乱码的问题之后,仍然有很多的问题需要我们解决。
现在放在我们面前的问题有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);
结果贴图: