2012-07-25 407 views
4

对我的软件的要求是,包含导出数据的文件的编码应为UTF8。但是当我将数据写入文件时,编码始终是ANSI。 (我用记事本+ +进行检查。)如何在C++中将文件编码格式设置为UTF8

目前我在做什么是试图文件通过阅读它,将其转换为UTF8和写作文本到一个新文件手动转换。

linestd::string
inputFilestd::ifstream
pOutputFileFILE*

// ... 

if(inputFile.is_open()) 
{ 
    while(inputFile.good()) 
    { 
     getline(inputFile,line); 

     //1 
     DWORD dwCount = MultiByteToWideChar(CP_ACP, 0, line.c_str(), -1, NULL, 0); 
     wchar_t *pwcharText; 
     pwcharText = new wchar_t[ dwCount]; 

     //2 
     MultiByteToWideChar(CP_ACP, 0, line.c_str(), -1, pwcharText, dwCount); 

     //3 
     dwCount = WideCharToMultiByte(CP_UTF8, 0, pwcharText, -1, NULL, 0, NULL, NULL); 
     char *pText; 
     pText = new char[ dwCount ]; 

     //4 
     WideCharToMultiByte(CP_UTF8, 0, pwcharText, -1, pText, dwCount, NULL, NULL); 

     fprintf(pOutputFile,pText); 
     fprintf(pOutputFile,"\n"); 

     delete[] pwcharText; 
     delete[] pText; 
    } 
} 

// ... 

不幸的是,编码仍然是ANSI。我搜索了一段时间的解决方案,但我总是遇到通过MultiByteToWideChar和WideCharToMultiByte的解决方案。但是,这似乎并不奏效。我在这里错过了什么?

我也在这里看到了一个解决方案,但大多数UTF8的问题处理C#和PHP的东西。

+2

如果你只写英文字符的文件,记事本+ +是在显示ANSI正确的,而且文件也将是UTF-8作为其ANSI/ASCII编码的所有英文字母UTF-8的有效子集。 – RedX 2012-07-25 09:15:06

+0

该文件将是一个包含英文字母,数字和一些特殊字符('/',';',':',',','。','(',')')的CSV文件。 – Exa 2012-07-25 09:19:55

+0

你的编译器是否支持[std :: codecvt_utf8](http://en.cppreference.com/w/cpp/locale/codecvt_utf8)? – 2012-07-25 09:21:41

回答

1

在Windows在VC++ 2010,可以使用本地化方面的std :: codecvt_utf8_utf16(尚未在GCC实现,因为据我所知)(即C++ 11)。 cppreference.com的示例代码具有读取/写入UTF-8文件所需的所有基本信息。

std::wstring wFromFile = _T("teststring"); 
std::wofstream fileOut("textOut.txt"); 
fileOut.imbue(std::locale(fileOut.getloc(), new std::codecvt_utf8_utf16<wchar_t>)); 
fileOut<<wFromFile; 

它将ANSI编码文件设置为UTF-8(在记事本中检查)。希望这是你所需要的。

0

AFAIK,fprintf()会进行字符转换,因此不能保证将UTF-8编码数据传递给它实际上会将UTF-8写入文件。既然你已经自己转换的数据,使用fwrite()代替你正在写的UTF-8的数据原样,如:

DWORD dwCount = MultiByteToWideChar(CP_ACP, 0, line.c_str(), line.length(), NULL, 0); 
if (dwCount == 0) continue; 

std::vector<WCHAR> utf16Text(dwCount); 
MultiByteToWideChar(CP_ACP, 0, line.c_str(), line.length(), &utf16Text[0], dwCount); 

dwCount = WideCharToMultiByte(CP_UTF8, 0, &utf16Text[0], utf16Text.size(), NULL, 0, NULL, NULL); 
if (dwCount == 0) continue; 

std::vector<CHAR> utf8Text(dwCount); 
WideCharToMultiByte(CP_UTF8, 0, &utf16Text[0], utf16Text.size(), &utf8Text[0], dwCount, NULL, NULL); 

fwrite(&utf8Text[0], sizeof(CHAR), dwCount, pOutputFile); 
fprintf(pOutputFile, "\n"); 
0

在Windows上,文件没有编码。每个应用程序都会根据自己的规则进行编码。最好的办法是在文件的前面放一个byte-order mark,并希望它能被识别。