vs下,GBK格式的.h .cpp 編譯時,自動轉換爲UTF-8

轉自

 http://suool.net/



在VS下面開發Cocos程序的時候,他的默認編碼是GBK的,但是在遷移或者是編譯調試的時候要求UTF的編碼更爲方便。因此便有了將C++文件的編碼格式轉換爲UTF-8的需求問題。

這個問題,當然可以在建立文件保存的時候選擇高級保存選擇,然後選擇保存的格式。

 
但是,顯然,在項目文件很多的時候,這個不是一個聰明的選擇。所以,就要想辦法如何批量的轉化處理。
在Linux下面有專門的命令可以實現這個功能。
在Windows下面要如何做呢?
當然,藉助於我們萬能的C++一樣可以很方便的解決它,經過一番查找資料,現在共享一下我的解決方法,首先,要在VS裏面建立一個VC的控制檯程序項目。
然後新建一個convert源文件。代碼如下:
⦁    //  定義控制檯應用程序的入口點。 
⦁    // 
⦁     
⦁    #include "stdafx.h" 
⦁    #include <afxwin.h> 
⦁    #include <string> 
⦁    #include <iostream> 
⦁     
⦁    #ifdef _DEBUG 
⦁    #define new DEBUG_NEW 
⦁    #endif 
⦁     
⦁    #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 
⦁     
⦁    // 唯一的應用程序對象 
⦁     
⦁    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()); 
⦁     
⦁                        TCHAR* fileName = new TCHAR[strFoundFile.GetLength() + 1]; 
⦁                        //wcscpy_s(*fileName, strFoundFile); 
⦁     
⦁                        // 中文路徑存在問題,可以將下面的輸出屏蔽,程序將靜默運行 
⦁                        printf("%S已經轉換爲UTF-8編碼", strFoundFile.GetBuffer(0)); 
⦁                        cout << endl; 
⦁     
⦁                        if (_tcslen(fileName) >0) 
⦁                        { 
⦁                            delete[] fileName; 
⦁                        } 
⦁                    } 
⦁                } 
⦁            } 
⦁        } 
⦁        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(); 
⦁    } 


如果編譯出現錯誤請點擊,項目--屬性--一般------MFC的使用選擇共享DLL的方式。
 
然後將編譯成功的.exe文件放在項目的目錄下,比如:
 
然後選擇項目,屬性的與生成事件,將要轉換的源碼目錄放在.exe 的後面即可,這樣雖然在您編寫的時候保存的是GBK,但是在項目進行編譯之前會把指定目錄下的所有C++源碼文件轉換爲UTF-8的格式,具體格式如下:
 
當然,您也可以直接在cmd中運行該exe文件,在後面加上要轉換的目錄即可。格式爲: convert.exe Dir
這樣在編譯之前就會先將源碼文件格式轉換爲UTF-8的格式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章