我是C++和MFC的新手。主要问题是我有一个需要翻译成俄语的 MFC 项目。我看到最好的选择是将项目更改为 Unicode,但我不能,因为这是一个巨大的项目,当我更改时,我收到 4000 多个错误。稍后我们将把所有代码传递给 Unicode,但现在我只需要在按钮和 CListBox 上显示西里尔字母。
好吧,主要是:如何使用多字节打印西里尔文?
谢谢大家!
PD:对不起,我将更明确地说明我尝试过的内容:
使用俄语区域设置:
setlocale(LC_ALL, "russian_russia.1251");
setlocale(LC_CTYPE, "rus");
但没有用。显示问号。
我也尝试使用函数WideCharToMultiByte进行转换。但显示的字符似乎编码错误。
std::string utf8_encode(const std::wstring &wstr)
{
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
wchar_t* wch = L"Привет";
std::string ch = utf8_encode(wch);
m_wndOutputBuild.AddString(ch.c_str()); //OUTPUT Привет
PD2:现在我这样打电话
setlocale(LC_ALL, "russian_russia.1251");
std::wstring wch = L"Привет";
std::string ch = encode_1251(wch);
m_wndOutputBuild.AddString(ch.c_str()); //OUTPUT Ïðèâåò
和功能:
std::string encode_1251(const std::wstring &wstr)
{
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(1251, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(1251, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
我发现Windows-1251在这里将CP放在WideCharToMultiByte上。
在utf8_encode
函数中,将 Unicode UTF-16 字符串转换为std::string
时,您将CP_UTF8
传递给WideCharToMultiByte
。然后你获取返回的 UTF-8std::string
,并通过.c_str()
将其传递给CListBox::AddString
方法。
但是,如果应用程序采用 MBCS 西里尔文,则应从 UTF-16 转换为西里尔文代码页(而不是 UTF-8),并将西里尔文代码页中编码的字符串传递给 MFC 类方法,如CListBox::AddString
。
换句话说,您可能希望将utf8_encode
函数替换为cyrillic_encode
函数,该函数将 UTF-16 文本作为输入,并将其转换为西里尔代码页:
// Convert from Unicode UTF-16 to Cyrillic code page
std::string cyrillic_encode(const std::wstring &utf16)
然后将返回的字符串传递给感兴趣的 MFC 类方法,例如:
// From Unicode UTF-16 to Cyrillic code page
std::string cyrillic_text = cyrillic_encode(wch);
// Show Cyrillic-encoded "MBCS" text
m_wndOutputBuild.AddString(cyrillic_text.c_str());
此外,正如@IInspectable在注释中正确指出的那样,请考虑在转换函数中添加适当的错误检查代码。事实上,一般来说,可能存在无法用西里尔文正确编码的 UTF-16 文本,因为后者是前者的适当子集。