我目前正在开发一个专门使用 UTF-8 的 MFC 程序。在某些时候,我必须将 UTF-8 数据写入文件;为此,我使用 CFiles 和 CStrings。
当我将 utf-8(更准确地说是俄语字符)数据写入文件时,输出看起来像
Ðàñïå÷àòàíî:
Ñèñòåìà
Ïðîèçâîäñòâî
等等。这肯定不是 utf-8。要正确读取这些数据,我必须更改我的系统设置;将非 ASCII 字符更改为俄语编码表确实有效,但随后我所有基于拉丁语的非 ASCII 字符都会失败。无论如何,我就是这样做的。
CFile CSVFile( m_sCible, CFile::modeCreate|CFile::modeWrite);
CString sWorkingLine;
//Add stuff into sWorkingline
CSVFile.Write(sWorkingLine,sWorkingLine.GetLength());
//Clean sWorkingline and start over
我错过了什么吗?我应该改用别的东西吗?有什么我错过的吗?程序员们,我会为您的智慧和经验而努力。
编辑:当然,正如我刚刚提出的一个问题,我终于找到了一些可能很有趣的东西,可以在这里找到。我想我可能会分享它。
编辑2:
好的,所以我将 BOM 添加到我的文件中,该文件现在包含中文字符,可能是因为我没有将我的行转换为 UTF-8。添加我做的bom...
char BOM[3]={0xEF, 0xBB, 0xBF};
CSVFile.Write(BOM,3);
在那之后,我添加了...
TCHAR TestLine;
//Convert the line to UTF-8 multibyte.
WideCharToMultiByte (CP_UTF8,0,sWorkingLine,sWorkingLine.GetLength(),TestLine,strlen(TestLine)+1,NULL,NULL);
//Add the line to file.
CSVFile.Write(TestLine,strlen(TestLine)+1);
但后来我无法编译,因为我真的不知道如何获得 TestLine 的长度。strlen 似乎不接受 TCHAR。 已修复,改为使用 1000 的静态长度。
编辑 3:
所以,我添加了这段代码......
wchar_t NewLine[1000];
wcscpy( NewLine, CT2CW( (LPCTSTR) sWorkingLine ));
TCHAR* TCHARBuf = new TCHAR[1000];
//Convert the line to UTF-8 multibyte.
WideCharToMultiByte (CP_UTF8,0,NewLine,1000,TCHARBuf,1000,NULL,NULL);
//Find how many characters we have to add
size_t size = 0;
HRESULT hr = StringCchLength(TCHARBuf, MAX_PATH, &size);
//Add the line to the file
CSVFile.Write(TCHARBuf,size);
它编译得很好,但是当我查看我的新文件时,它与我没有所有这些新代码时完全相同(例如:Ðàñïå÷àòàíî:)。感觉就像我没有向前迈出一步,虽然我想只有一件小事让我与胜利分开。
编辑4:
正如 Nate 所要求的,我删除了之前添加的代码,我决定改用他的代码,这意味着现在,当我要添加我的行时,我已经......
CT2CA outputString(sWorkingLine, CP_UTF8);
//Add line to file.
CSVFile.Write(outputString,::strlen(outputString));
一切都编译得很好,但是俄语字符显示为???????。越来越近,但仍然不是那样。顺便说一句,我要感谢所有试图/试图帮助我的人,非常感谢。我已经坚持了一段时间了,我等不及这个问题消失了。
最终编辑(我希望)通过改变我第一次获得 UTF-8 字符的方式(我在不知道的情况下重新编码),这与我输出文本的新方式是错误的,我得到了可以接受的结果。通过在我的文件开头添加 UTF-8 BOM 字符,它可以在其他程序(如 Excel)中读取为 Unicode。
欢呼!谢谢大家!