PC版ゲーム--cocos 2 d-x中国語の文字化けし解決方法(GBKからUTF-8コード)とそのfatal error:iconviconv.h:No such file or directory問題
10048 ワード
<1>原因:これはVCがGBK符号化を採用し、cococos 2 d-xがUTF-8符号化を採用し、符号化方法が一致しないためである.
<2>解決策:
libiconvを追加します.lib.手順:参照-->構成プロパティ-->コネクタ-->入力-->依存項目を追加libiconvを追加します.lib
<3>iconv.hはClassesの下に追加されます.そのうちiconv.hの内容は以下の通りである.
<4>ファイルを追加するTool.hとToolcpp、内容は以下の通りです.
Tool.h
<2>解決策:
libiconvを追加します.lib.手順:参照-->構成プロパティ-->コネクタ-->入力-->依存項目を追加libiconvを追加します.lib
<3>iconv.hはClassesの下に追加されます.そのうちiconv.hの内容は以下の通りである.
/* Copyright (C) 1999-2003 Free Software Foundation, Inc.
This file is part of the GNU LIBICONV Library.
The GNU LIBICONV Library is free software; you can redistribute it
and/or modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
The GNU LIBICONV Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU LIBICONV Library; see the file COPYING.LIB.
If not, write to the Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA. */
/* When installed, this file is called "iconv.h". */
#ifndef _LIBICONV_H
#define _LIBICONV_H
#define _LIBICONV_VERSION 0x0109 /* version number: (major<<8) + minor */
extern int _libiconv_version; /* Likewise */
/* We would like to #include any system header file which could define
iconv_t, 1. in order to eliminate the risk that the user gets compilation
errors because some other system header file includes /usr/include/iconv.h
which defines iconv_t or declares iconv after this file, 2. when compiling
for LIBICONV_PLUG, we need the proper iconv_t type in order to produce
binary compatible code.
But gcc's #include_next is not portable. Thus, once libiconv's iconv.h
has been installed in /usr/local/include, there is no way any more to
include the original /usr/include/iconv.h. We simply have to get away
without it.
Ad 1. The risk that a system header file does
#include "iconv.h" or #include_next "iconv.h"
is small. They all do #include <iconv.h>.
Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It
has to be a scalar type because (iconv_t)(-1) is a possible return value
from iconv_open().) */
/* Define iconv_t ourselves. */
#undef iconv_t
#define iconv_t libiconv_t
typedef void* iconv_t;
/* Get size_t declaration. */
#include <stddef.h>
/* Get errno declaration and values. */
#include <errno.h>
/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS,
have EILSEQ in a different header. On these systems, define EILSEQ
ourselves. */
#ifndef EILSEQ
/* Igor: called upon EILSEQ from glibc, since autogeneration of this header
on Windows didn't do the job. */
/* #define EILSEQ @EILSEQ@ */
#define EILSEQ 84
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Allocates descriptor for code conversion from encoding `fromcode' to
encoding `tocode'. */
#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif
extern iconv_t iconv_open (const char* tocode, const char* fromcode);
/* Converts, using conversion descriptor `cd', at most `*inbytesleft' bytes
starting at `*inbuf', writing at most `*outbytesleft' bytes starting at
`*outbuf'.
Decrements `*inbytesleft' and increments `*inbuf' by the same amount.
Decrements `*outbytesleft' and increments `*outbuf' by the same amount. */
#ifndef LIBICONV_PLUG
#define iconv libiconv
#endif
extern size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
/* Frees resources allocated for conversion descriptor `cd'. */
#ifndef LIBICONV_PLUG
#define iconv_close libiconv_close
#endif
extern int iconv_close (iconv_t cd);
#ifndef LIBICONV_PLUG
/* Nonstandard extensions. */
/* Control of attributes. */
#define iconvctl libiconvctl
extern int iconvctl (iconv_t cd, int request, void* argument);
/* Requests for iconvctl. */
#define ICONV_TRIVIALP 0 /* int *argument */
#define ICONV_GET_TRANSLITERATE 1 /* int *argument */
#define ICONV_SET_TRANSLITERATE 2 /* const int *argument */
#define ICONV_GET_DISCARD_ILSEQ 3 /* int *argument */
#define ICONV_SET_DISCARD_ILSEQ 4 /* const int *argument */
/* Listing of locale independent encodings. */
#define iconvlist libiconvlist
extern void iconvlist (int (*do_one) (unsigned int namescount,
const char * const * names,
void* data),
void* data);
/* Support for relocatable packages. */
/* Sets the original and the current installation prefix of the package.
Relocation simply replaces a pathname starting with the original prefix
by the corresponding pathname with the current prefix instead. Both
prefixes should be directory names without trailing slash (i.e. use ""
instead of "/"). */
extern void libiconv_set_relocation_prefix (const char *orig_prefix,
const char *curr_prefix);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _LIBICONV_H */
<4>ファイルを追加するTool.hとToolcpp、内容は以下の通りです.
Tool.h
#ifndef _Tool_
#define _Tool_
#include "cocos2d.h"
#include "iconv.h"
#include <iostream>
#include <string.h>
int code_convert(const char *from_charset, const char *to_charset, const char *inbuf, size_t inlen, char *outbuf, size_t outlen);
/*UTF8תΪGB2312*/
std::string u2a(const char *inbuf);
/*GB2312תΪUTF8*/
std::string a2u(const char *inbuf);
#endif
Tool.cpp
#include "Tool.h" int code_convert(const char *from_charset, const char *to_charset, const char *inbuf, size_t inlen, char *outbuf, size_t outlen) { 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(iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1; iconv_close(cd); return 0; } /*UTF8תΪGB2312*/ std::string u2a(const char *inbuf) { size_t inlen = strlen(inbuf); char * outbuf = new char[inlen * 2 + 2]; std::string strRet; if(code_convert("utf-8", "gb2312", inbuf, inlen, outbuf, inlen * 2 + 2) == 0) { strRet = outbuf; } delete [] outbuf; return strRet; } /*GB2312תΪUTF8*/ std::string a2u(const char *inbuf) { size_t inlen = strlen(inbuf); char * outbuf = new char[inlen * 2 + 2]; std::string strRet; if(code_convert("gb2312", "utf-8", inbuf, inlen, outbuf, inlen * 2 + 2) == 0) { strRet = outbuf; } delete [] outbuf; return strRet; }
<4>a 2 uを使用すればよい.
<5>フィールドテキストがutf 8形式であるか否かを判断する、そうであれば、トランスコードを必要とせず、トランスコードを必要とする.#ifndef _UTFUtils_ #define _UTFUtils_ class MyUTF { public: static bool isUTF8(const char *pText, int nLen) { // octets to go in this UTF-8 encoded character unsigned long dwOctets; unsigned char chr; bool bAllAscii= true; // dwOctets = 0; for (int i = 0; i < nLen; i++) { // chr = *(pText + i); if ((chr & 0x80) != 0) // ascii bAllAscii = false; if (dwOctets == 0) { // 7 bit ascii after 7 bit ascii is just fine. Handle start of encoding case if (chr >= 0x80) { // count of the leading 1 bits is the number of characters encoded do { chr <<= 1; dwOctets++; } while ((chr & 0x80) != 0); // count includes this character dwOctets--; //if (dwOctets == 0) if (dwOctets < 2) // must start with 11xxxxxx return false; } } else { // non-leading bytes must start as 10xxxxxx if ((chr & 0xC0) != 0x80) return false; // processed another octet in encoding dwOctets--; } } // End of text. Check for consistency if (dwOctets > 0) // anything left over at the end is an error return false; if (bAllAscii) // Not utf-8 if all ascii. Forces caller to use code pages for conversion return false; return true; } }; #endif
参照する場合は、次のように使用されます.
#include "C:/cocos2d-x-2.2.5/cocos2d-x-2.2.5/projects/IGuanGanKing_2014_10_29/Classes/UTFUtils.h"
の絶対パス
<6>UILabelvoid Label::setText(const std::string& text) { if(!MyUTF::isUTF8(text.c_str(), text.size())) _labelRenderer->setString(a2u(text.c_str()).c_str()); else _labelRenderer->setString(text.c_str()); labelScaleChangedWithSize(); }
<7>UILabelBMFontvoid LabelBMFont::setText(const char* value) { if (!value) { return; } _stringValue = value; if (!_fntFileHasInit) { return; } const std::string& str = value; if(!MyUTF::isUTF8(str.c_str(), str.size())) _labelBMFontRenderer->setString(a2u(value).c_str()); else _labelBMFontRenderer->setString(value); labelBMFontScaleChangedWithSize(); }
<8>
注意1つの問題:unicodeとutf 8が一緒にミキシングされた場合、setTextを実行することができなくなり、表示できなくなる.例:btn->setTitleText(toStr(" %i ",info->getMaxNum())->getCString());
info->getMaxNum()はサーバから読み出すutf 8符号化であり、vs自体が持つフォントは「サイン」、「次」はUnicodeであるため、全体が一緒になると文字化けしてしまう.
ソリューション:string signStr = a2u(" "); signStr += CCString::createWithFormat("%i", info->getMaxNum())->getCString(); signStr += a2u(" ");
対応関係:
Unicode<-->GBK
ANSI<-->utf8