C++文件编码由GBK转换UTF-8的解决方法

原创 2015年03月25日 00:19:05

在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


当然使用Python写个脚本来转换也是可以的。这个问题要解决还是有很多的方法的。

That's all.

希望有帮助到您。

C++中 Unicode 与 UTF-8 编码互转

1、简述最近在发送网络请求时遇到了中文字符乱码的问题,在代码中调试字符正常,用抓包工具抓的包中文字符显示正常,就是发送到服务器就显示乱码了,那就要将客户端和服务器设置统一的编码(UTF-8),而我们程...
  • GoForwardToStep
  • GoForwardToStep
  • 2016-11-17 22:44:21
  • 10511

C++中ANSI、Unicode16、UTF-8字符串之间的互转

更多文章点击这里 敲黑板 在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte...
  • u013713061
  • u013713061
  • 2017-10-30 17:11:27
  • 389

C++中GB2312字符串和UTF-8之间的转换 从CString 的转换

在编程过程中需要对字符串进行不同的转换,特别是Gb2312和Utf-8直接的转换。在几个开源的魔兽私服中,很多都是老外开发的,而暴雪为了能 够兼容世界上的各个字符集也使用了UTF-8。在中国使用VS(...
  • liu0115
  • liu0115
  • 2015-08-23 10:27:57
  • 1305

c++ string、UTF8相互转换方法

c++ string、UTF8相互转换方法 std::string ofDewarServer::string_To_UTF8(const std::string & str) std::stri...
  • liyu1128
  • liyu1128
  • 2013-10-29 13:27:52
  • 18986

C++ 字符串UTF8与GBK转化

//UTF8转化为GBK格式void ConvertUtf8ToGBK(CString &strUtf8){    int len=MultiByteToWideChar(CP_UTF8, 0, (L...
  • segen_jaa
  • segen_jaa
  • 2011-05-26 16:23:00
  • 15263

C/C++,字符串的UTF-8与GBK(或GB2312)编码转换

转: C/C++,字符串的UTF-8与GBK(或GB2312)编码转换 写代码时经常会遇到各种编码转换问题,因此记录下来以便日后对各种平台下不同编码转换作整理。 C/C++: G...
  • liuhhaiffeng
  • liuhhaiffeng
  • 2016-12-07 13:13:26
  • 1971

c++字符串编码GBK到UTF8的转换

使用c++跨windows和linux平台实现字符串GBK到UTF8的转换。 原理是GBK字符串先转为unicode编码,然后再转换为UTF8编码。...
  • jiayichendddd
  • jiayichendddd
  • 2015-05-09 19:27:12
  • 2336

GBK到UTF8编码转换C++实现

#include #include #include #include using namespace std;string GBKToUTF8(const std::string& strG...
  • feihuadao
  • feihuadao
  • 2017-03-13 13:40:53
  • 2637

VC++ UTF-8与GBK格式转换

声明:本人一个菜鸟,网上搜罗了很多关于VC++编程的资料,可每本资料都是涵盖面太广,难以细致。英语又太烂,所以不得意只得摸索,恐又忘记所以记在此处,若有不对的地方,烦劳指出,不胜感激。 author...
  • fym0121
  • fym0121
  • 2012-05-08 20:12:23
  • 8245

关于c++中utf8和gbk编码方式的转换

GBK转utf8如下:string GBKToUTF8(const std::string& strGBK) { string strOutUTF8 = ""; WCHAR...
  • u013230291
  • u013230291
  • 2016-12-29 14:15:46
  • 2011
收藏助手
不良信息举报
您举报文章:C++文件编码由GBK转换UTF-8的解决方法
举报原因:
原因补充:

(最多只允许输入30个字)