gpt4 book ai didi

c++ - UTF-8、CString 和 CFile? (C++,MFC)

转载 作者:IT老高 更新时间:2023-10-28 22:24:50 45 4
gpt4 key购买 nike

我目前正在开发一个必须使用 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。

万岁!谢谢大家!

最佳答案

当你输出数据时你需要做的(这里假设你是在 Unicode 模式下编译,强烈推荐):

CString russianText = L"Привет мир";

CFile yourFile(_T("yourfile.txt"), CFile::modeWrite | CFile::modeCreate);

CT2CA outputString(russianText, CP_UTF8);
yourFile.Write(outputString, ::strlen(outputString));

如果 _UNICODE 未定义(您正在使用多字节模式),您需要知道输入文本所在的代码页并将其转换为您可以使用的内容。此示例显示如何处理 UTF-16 格式的俄语文本,并将其保存为 UTF-8:

// Example 1: convert from Russian text in UTF-16 (note the "L"
// in front of the string), into UTF-8.
CW2A russianTextAsUtf8(L"Привет мир", CP_UTF8);
yourFile.Write(russianTextAsUtf8, ::strlen(russianTextAsUtf8));

更有可能的是,您的俄语文本位于其他代码页中,例如 KOI-8R。在这种情况下,您需要将其他代码页转换为 UTF-16。然后将 UTF-16 转换为 UTF-8。您不能使用转换宏直接从 KOI-8R 转换为 UTF-8,因为它们总是尝试将窄文本转换为系统代码页。所以最简单的方法就是这样做:

// Example 2: convert from Russian text in KOI-8R (code page 20866)
// to UTF-16, and then to UTF-8. Conversions between UTFs are
// lossless.
CA2W russianTextAsUtf16("\xf0\xd2\xc9\xd7\xc5\xd4 \xcd\xc9\xd2", 20866);
CW2A russianTextAsUtf8(russianTextAsUtf16, CP_UTF8);
yourFile.Write(russianTextAsUtf8, ::strlen(russianTextAsUtf8));

您不需要 BOM(它是可选的;除非有特定原因,否则我不会使用它)。

请务必阅读此内容:http://msdn.microsoft.com/en-us/library/87zae4a3(VS.80).aspx .如果你错误地使用了CT2CA(例如,使用赋值运算符)你会遇到麻烦。链接的文档页面显示了如何使用和不使用它的示例。

更多信息:

  • CT2CA中的C表示const。我尽可能使用它,但某些转换仅支持非常量版本(例如 CW2A)。
  • CT2CA 中的 T 表示您将 转换为 LPCTSTR .因此,无论您的代码是否使用 _UNICODE 标志编译,它都会起作用。您也可以使用 CW2A(其中 W 表示宽字符)。
  • CT2CA 中的 A 表示您正在转换为“ANSI”(8 位字符)字符串。
  • 最后,CT2CA 的第二个参数表示您要转换到的代码页。

要进行反向转换(从 UTF-8 到 LPCTSTR),您可以:

CString myString(CA2CT(russianText, CP_UTF8));

在这种情况下,我们将 UTF-8 格式的“ANSI”字符串转换为 LPCTSTR。 LPCTSTR 始终假定为 UTF-16(如果定义了 _UNICODE)或当前系统代码页(如果未定义 _UNICODE) .

关于c++ - UTF-8、CString 和 CFile? (C++,MFC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2318481/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com