自動將visual stdio建立的檔案從gb2312編碼轉換成utf8編碼
cocos2d-x是一個不錯的手機遊戲框架,不過由於在中文的windows系統下使用visual stdio2008預設建立的類檔案,包括.h和.cpp,其檔案編碼都是gb2312的。當將這些檔案在cygwin上用ndk編譯時,雖然編譯沒問題,但其中的中文在讀取的時候會出現亂碼,這是cocos2d-x的一個不足,例如CCLabelTTF顯示中文的時候會出現亂碼,而且CCSpriteFrame的spriteFrameByName方法也不能傳入中文,這確實是一件頭疼的事。
解決方法有兩種,一種是將原始碼檔案儲存為utf8格式,另一種方法在使用中文字元的時候轉碼,如果使用第二種方法的,為了跨平臺,一般使用iconv這個庫進行編碼轉換。但由於iconv是基於LGPL協議,cocos2d-x已經在
第二種方法則是將原始碼檔案編碼轉換為utf8編碼,手動的方法是在visual stdio的檔案選單裡有一個高階儲存選項,將編碼設為Unicode(UTF8帶簽名)然後儲存即可,不過這種方法比較笨,純粹是體力活。我研究過打算修改一下visual stdio的類嚮導,想把類嚮導建立的檔案修改為utf8格式,但不得其果。如果是單純的建立.h和.cpp檔案則是可以的,方法是將Microsoft
Visual Studio 9.0/VC/vcprojectitems
// ChangeFileEncoding.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include "ChangeFileEncoding.h" #include <string> #ifdef _DEBUG #define new DEBUG_NEW #endif // 唯一的應用程式物件 CWinApp theApp; using namespace std; void recursiveFile(CString strFileType); void convertGBToUTF8(CString strWritePath, const char* gb2312); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // 初始化 MFC 並在失敗時顯示錯誤 if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: 更改錯誤程式碼以符合您的需要 _tprintf(_T("錯誤: MFC 初始化失敗\n")); nRetCode = 1; } else { /*for(int i = 0; i < argc; i++) { MessageBox(NULL, argv[i], L"Arglist contents", MB_OK); }*/ //宣告一個CFileFind類變數,以用來搜尋 //接受一個引數作為原始碼檔案的根目錄 TCHAR *lpszDirName = argv[1]; CString strFileType; strFileType.Format(_T("%s\\*.*"), lpszDirName); //遞迴此目錄下的.h檔案和.cpp檔案,如果發現不是utf8編碼則轉換為utf8編碼 recursiveFile(strFileType); } return nRetCode; } void recursiveFile( CString strFileType) { CFileFind finder; BOOL isFinded = finder.FindFile(strFileType);//查詢第一個檔案 while(isFinded) { isFinded = finder.FindNextFile(); //遞迴搜尋其他的檔案 if(!finder.IsDots()) //如果不是"."目錄 { CString strFoundFile = finder.GetFilePath(); if(finder.IsDirectory()) //如果是目錄,則遞迴地呼叫 { CString strNextFileType; strNextFileType.Format(_T("%s\\*.*"), strFoundFile); recursiveFile(strNextFileType); } else { //如果是標頭檔案或cpp檔案 if(strFoundFile.Right(4) == _T(".cpp") || strFoundFile.Right(2) == _T(".h")) { CFile fileReader(strFoundFile, CFile::modeRead); byte head[3]; fileReader.Read(head, 3); //判斷是否帶有BOM檔案頭 if(head[0] == 0xef && head[1]==0xbb && head[2] == 0xbf ) { fileReader.Close(); continue; } fileReader.SeekToBegin(); int bufLength = 256; char *buf = new char[bufLength]; ZeroMemory(buf, bufLength); int nReadLength; std::string strContent; while((nReadLength = fileReader.Read(buf, bufLength))) { strContent.append(buf, nReadLength); ZeroMemory(buf, nReadLength); } delete buf; fileReader.Close(); convertGBToUTF8(strFoundFile, strContent.c_str()); } } } } finder.Close(); } void convertGBToUTF8(CString strWritePath, const char* gb2312) { CFile fp; fp.Open(strWritePath, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary,NULL); int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0); wchar_t* wstr = new wchar_t[len+1]; memset(wstr, 0, len+1); MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len+1]; memset(str, 0, len+1); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); if(wstr) delete[] wstr; str[len] = '\n'; const unsigned char aryBOM[] = {0xEF, 0xBB, 0xBF}; fp.Write(aryBOM, sizeof(aryBOM)); fp.Write(str,len); delete[] str; fp.Close(); }
編碼生成ChangeFileEncoding.exe後,將ChangeFileEncoding.exe放在cocos2d-x的主程式專案的根目錄下里,例如專案的目錄樹如下:
Project
----------\cocos2dx
----------\CocosDenshion
----------\Box2D
----------\MainApplication
這裡MainApplication就是主程式專案,將ChangeFileEncoding.exe放在此目錄下,然後設定MainApplication的專案屬性,在"生成事件" --"預生成事件" --"命令列"裡填入“ChangeFileEncoding.exe ./Classes”即可。這樣每次新增的檔案雖然是gb2312編碼,但每次在編譯前會自動轉換成utf8編碼。
需要原始碼的請留下郵箱。