【问题标题】:Unicode not printingUnicode 不打印
【发布时间】:2014-05-15 14:22:56
【问题描述】:

我有以下 C++ 代码

char* locale = setlocale(LC_ALL, "German"); // Get the CRT's current locale.
std::locale lollocale(locale);
setlocale(LC_ALL, locale); // Restore the CRT.
wcout.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT.

COORD cur = { 0, 0 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cur);
wcout << L"Enemy " << this->enemyStrengthLeft << L"/" << this->enemyStrength << endl;
wcout << L"◄";
for (int i = 0; i < 20; i++) {
  if (i % 2 == 0)
    wcout << L"■";
  else
    wcout << L" ";
}
wcout << L"►" << endl;

当我执行它时,unicode字符不在cmd窗口中,我该如何解决?

编辑

我使用 Lucida Console 作为字体。

编辑 2

如果有帮助,我正在 Windows 7 Enterprise SP1 64 位下运行 Visual Studio 2013 Express for Desktop

【问题讨论】:

  • 您的控制台窗口是否使用 TrueType 字体?
  • 哦,对了,我要输入字体了。
  • 这看起来像 Windows,在这种情况下,它需要 _setmode(_fileno(stdout), _O_WTEXT); 才能将宽字符串发送到标准输出。
  • 字符不显示是什么情况?它们是被遗漏、被替换,还是整个输出流在第一个 unicode 字符之后“停止”?
  • @Cubbi 是的,它是 Windows,但是我需要哪些头文件来解决你的“技巧”?

标签: c++ winapi unicode


【解决方案1】:

Windows 不能通过标准库很好地支持 Unicode。可以通过标准库将任意 Unicode 打印到控制台,但不是很方便,而且我知道的所有方法都有不愉快的副作用。

只需使用 Windows API:

std::wstring s = L"◄ ■ ►";
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), s.c_str(), s.size(), nullptr, nullptr);

顺便说一句,您获取语言环境并恢复它的代码并没有按照您的想法进行,但有更好的方法。

char* locale = setlocale(LC_ALL, "German"); // Get the CRT's current locale.
std::locale lollocale(locale);
setlocale(LC_ALL, locale); // Restore the CRT.

setlocale 返回函数运行后 生效的语言环境名称。所以你总是会得到一个德语语言环境的名称,而全局语言环境不会恢复到它的原始值。如果您真的想获取当前设置的语言环境,则可以通过传递 nullptr 而不是语言环境名称来实现:

char const *locale = std::setlocale(LC_ALL, nullptr);

这将获取当前语言环境而不更改它。

但是您应该知道,除非在某个时候更改了语言环境,否则它将是“C”语言环境。 C 和 C++ 程序始终在此语言环境中启动。 “C”语言环境不一定允许您使用基本源字符集之外的字符(甚至不包括所有 ASCII,更不用说像 'ä'、'ö'、'ü'、'ß'、'◄ '、'■' 和 '►'。

如果您想获取用户机器配置使用的语言环境,则可以使用空字符串作为名称。您还可以使用此语言环境为流灌输,而无需考虑全局语言环境。

cout.imbue(std::locale("")); // just imbue a stream

char const *locale = std::setlocale(LC_ALL, ""); // set global locale to user's preferred locale, and get the name of that locale.

【讨论】:

  • 有效,但我有点好奇为什么这有效,但我的解决方案无效。我的解决方案只适用于德语 ä、ö、ü 和 ß...
  • 因为这些字符是与您的语言环境相关的字符集的成员,并且它们在该编码中的表示恰好与您当前的控制台输出代码页中的编码相同。 (语言环境编码为 cp1252,控制台代码页为 cp850。)
  • 非常感谢 :) 我使用了你的解决方案 :)
  • blog.kalmbachnet.de/?postid=98你需要在CRT中启用unicode支持:_setmode(_fileno(stdout), _O_U16TEXT);
  • @JochenKalmbach 是的,这是替代方案之一。缺点是您必须消除所有基于字符的输出,因为printfcout 等会在启用该模式时崩溃。
猜你喜欢
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 2015-05-30
相关资源
最近更新 更多