【发布时间】:2011-01-20 01:57:41
【问题描述】:
我目前正在开发一个必须使用 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
我错过了什么吗?我应该改用别的东西吗?有什么我错过的吗? 程序员们,我会为您的智慧和经验而努力。
编辑: 当然,正如我刚刚提出的一个问题,我终于找到了一些可能很有趣的东西,可以在here 找到。想我可以分享一下。
编辑 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。
万岁!谢谢大家!
【问题讨论】:
-
您需要使用 _tcslen 来获取 TCHAR 字符串的长度。比如:TCHAR* testTCHAR = _T("test"); int tcharLength = _tcslen(testTCHAR);
-
另外,如果您需要将 CString 转换为 TCHAR* 字符串,请尝试此 CString testCString = _T("test"); TCHAR* testTCHAR = testCString.GetBuffer();
-
你工作太辛苦了。将
CT2CA与第二个参数CP_UTF8一起使用。请参阅下面的帖子。
标签: c++ mfc utf-8 cstring cfile