轉自
http://suool.net/
這個問題,當然可以在建立文件保存的時候選擇高級保存選擇,然後選擇保存的格式。
但是,顯然,在項目文件很多的時候,這個不是一個聰明的選擇。所以,就要想辦法如何批量的轉化處理。
在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的格式。