如何在C++中将文件编码格式设置为UTF8
问题描述:
对我的软件的要求是,包含导出数据的文件的编码应为UTF8。但是当我将数据写入文件时,编码始终是ANSI。 (我用记事本+ +进行检查。)如何在C++中将文件编码格式设置为UTF8
目前我在做什么是试图文件通过阅读它,将其转换为UTF8和写作文本到一个新文件手动转换。
line
是std::string
inputFile
是std::ifstream
pOutputFile
是FILE*
// ...
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的东西。
答
在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(在记事本中检查)。希望这是你所需要的。
答
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");
如果你只写英文字符的文件,记事本+ +是在显示ANSI正确的,而且文件也将是UTF-8作为其ANSI/ASCII编码的所有英文字母UTF-8的有效子集。 – RedX 2012-07-25 09:15:06
该文件将是一个包含英文字母,数字和一些特殊字符('/',';',':',',','。','(',')')的CSV文件。 – Exa 2012-07-25 09:19:55
你的编译器是否支持[std :: codecvt_utf8](http://en.cppreference.com/w/cpp/locale/codecvt_utf8)? – 2012-07-25 09:21:41