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

原帖地址:馍励网http://www.dabenmo.com/thread-22315-1-1.html

<font Color="#000">在VS下面开发Cocos程序的时候,他的默认编码是GBK的,但是在迁移或者是编译调试的时候要求UTF的编码更为方便。因此便有了将C++文件的编码格式转换为UTF-8的需求问题。


这个问题,当然可以在建立文件保存的时候选择高级保存选择,然后选择保存的格式。

C++文件编码由GBK转换UTF-8的解决方法_第1张图片

但是,显然,在项目文件很多的时候,这个不是一个聪明的选择。所以,就要想办法如何批量的转化处理。

在Linux下面有专门的命令可以实现这个功能。

在Windows下面要如何做呢?

当然,借助于我们万能的C++一样可以很方便的解决它,经过一番查找资料,现在共享一下我的解决方法,首先,要在VS里面建立一个VC的控制台程序项目。

然后新建一个convert源文件。代码如下:

  1. //  定义控制台应用程序的入口点。
  2. //

  3. #include "stdafx.h"
  4. #include <afxwin.h>
  5. #include <string>
  6. #include <iostream>

  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif

  10. #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1

  11. // 唯一的应用程序对象

  12. CWinApp theApp;

  13. using namespace std;

  14. void recursiveFile(CString strFileType);
  15. void convertGBToUTF8(CString strWritePath, const char* gb2312);

  16. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  17. {
  18.         int nRetCode = 0;

  19.         // 初始化 MFC 并在失败时显示错误
  20.         if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  21.         {
  22.                 // TODO: 更改错误代码以符合您的需要
  23.                 _tprintf(_T("错误: MFC 初始化失败\n"));
  24.                 nRetCode = 1;
  25.         }
  26.         else
  27.         {
  28.                 /*for(int i = 0; i < argc; i++)
  29.                 {
  30.                 MessageBox(NULL, argv[i], L"Arglist contents", MB_OK);
  31.                 }*/
  32.                 //声明一个CFileFind类变量,以用来搜索

  33.                 //接受一个参数作为源代码文件的根目录
  34.                 TCHAR *lpszDirName = argv[1];
  35.                 CString strFileType;
  36.                 strFileType.Format(_T("%s\\*.*"), lpszDirName);
  37.                 //递归此目录下的.h文件和.cpp文件,如果发现不是utf8编码则转换为utf8编码
  38.                 recursiveFile(strFileType);

  39.         }

  40.         return nRetCode;
  41. }

  42. void recursiveFile(CString strFileType)
  43. {
  44.         CFileFind finder;
  45.         BOOL isFinded = finder.FindFile(strFileType);//查找第一个文件
  46.         while (isFinded)
  47.         {
  48.                 isFinded = finder.FindNextFile(); //递归搜索其他的文件
  49.                 if (!finder.IsDots()) //如果不是"."目录
  50.                 {
  51.                         CString strFoundFile = finder.GetFilePath();
  52.                         if (finder.IsDirectory()) //如果是目录,则递归地调用
  53.                         {
  54.                                 CString strNextFileType;
  55.                                 strNextFileType.Format(_T("%s\\*.*"), strFoundFile);
  56.                                 recursiveFile(strNextFileType);
  57.                         }
  58.                         else
  59.                         {
  60.                                 //如果是头文件或cpp文件
  61.                                 if (strFoundFile.Right(4) == _T(".cpp") || strFoundFile.Right(2) == _T(".h")) {
  62.                                         CFile fileReader(strFoundFile, CFile::modeRead);
  63.                                         byte head[3];
  64.                                         fileReader.Read(head, 3);
  65.                                         //判断是否带有BOM文件头
  66.                                         if (head[0] == 0xef && head[1] == 0xbb && head[2] == 0xbf)
  67.                                         {
  68.                                                 fileReader.Close();
  69.                                                 continue;
  70.                                         }
  71.                                         fileReader.SeekToBegin();

  72.                                         int bufLength = 256;
  73.                                         char *buf = new char[bufLength];
  74.                                         ZeroMemory(buf, bufLength);
  75.                                         int nReadLength;
  76.                                         std::string strContent;
  77.                                         while ((nReadLength = fileReader.Read(buf, bufLength)))
  78.                                         {
  79.                                                 strContent.append(buf, nReadLength);
  80.                                                 ZeroMemory(buf, nReadLength);
  81.                                         }
  82.                                         delete buf;
  83.                                         fileReader.Close();
  84.                                         convertGBToUTF8(strFoundFile, strContent.c_str());

  85.                                         TCHAR* fileName = new TCHAR[strFoundFile.GetLength() + 1];
  86.                                         //wcscpy_s(*fileName, strFoundFile);

  87.                                         // 中文路径存在问题,可以将下面的输出屏蔽,程序将静默运行
  88.                                         printf("%S已经转换为UTF-8编码", strFoundFile.GetBuffer(0));
  89.                                         cout << endl;

  90.                                         if (_tcslen(fileName) >0)
  91.                                         {
  92.                                                 delete[] fileName;
  93.                                         }
  94.                                 }
  95.                         }
  96.                 }
  97.         }
  98.         finder.Close();
  99. }

  100. void convertGBToUTF8(CString strWritePath, const char* gb2312)
  101. {
  102.         CFile fp;
  103.         fp.Open(strWritePath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary, NULL);
  104.         int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
  105.         wchar_t* wstr = new wchar_t[len + 1];
  106.         memset(wstr, 0, len + 1);
  107.         MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
  108.         len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
  109.         char* str = new char[len + 1];
  110.         memset(str, 0, len + 1);
  111.         len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
  112.         if (wstr) delete[] wstr;
  113.         str[len] = '\n';
  114.         const unsigned char aryBOM[] = { 0xEF, 0xBB, 0xBF };
  115.         fp.Write(aryBOM, sizeof(aryBOM));
  116.         fp.Write(str, len);
  117.         delete[] str;
  118.         fp.Close();
  119. }
复制代码

如果编译出现错误请点击,项目--属性--一般------MFC的使用选择共享DLL的方式。

C++文件编码由GBK转换UTF-8的解决方法_第2张图片

然后将编译成功的.exe文件放在项目的目录下,比如:

C++文件编码由GBK转换UTF-8的解决方法_第3张图片

然后选择项目,属性的与生成事件,将要转换的源码目录放在.exe 的后面即可,这样虽然在您编写的时候保存的是GBK,但是在项目进行编译之前会把指定目录下的所有C++源码文件转换为UTF-8的格式,具体格式如下:

C++文件编码由GBK转换UTF-8的解决方法_第4张图片

当然,您也可以直接在cmd中运行该exe文件,在后面加上要转换的目录即可。格式为: convert.exe Dir


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

That's all.

希望有帮助到您。



你可能感兴趣的:(C++文件编码由GBK转换UTF-8的解决方法)