程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++文件編碼由GBK轉換UTF-8的解決方法

C++文件編碼由GBK轉換UTF-8的解決方法

編輯:C++入門知識

C++文件編碼由GBK轉換UTF-8的解決方法


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

 

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

\

但是,顯然,在項目文件很多的時候,這個不是一個聰明的選擇。所以,就要想辦法如何批量的轉化處理。

在Linux下面有專門的命令可以實現這個功能。

在Windows下面要如何做呢?

當然,借助於我們萬能的C++一樣可以很方便的解決它,經過一番查找資料,現在共享一下我的解決方法,首先,要在VS裡面建立一個VC的控制台程序項目。

然後新建一個convert源文件。代碼如下:

 

//  定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include 
#include 
#include 

#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

 

當然使用Python寫個腳本來轉換也是可以的。這個問題要解決還是有很多的方法的。

That's all.

希望有幫助到您。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved