在Windows控制台应用程序中输出unicodestring

您好我试图输出unicodestring与控制台与iostreams和失败。

我发现这一点: 在c + +控制台应用程序中使用unicode字体和此代码段的作品。

SetConsoleOutputCP(CP_UTF8); wchar_t s[] = L"èéøÞǽлљΣæča"; int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); char* m = new char[bufferSize]; WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL); wprintf(L"%S", m); 

但是,我没有find任何方法正确输出与iostreams的Unicode。 有什么build议么?

这不起作用:

 SetConsoleOutputCP(CP_UTF8); utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet()); wcout.imbue(utf8_locale); wcout << L"¡Hola!" << endl; 

编辑我找不到任何其他的解决scheme,而不是把这个片段包在一个stream中。 希望有人有更好的想法。

 //Unicode output for a Windows console ostream &operator-(ostream &stream, const wchar_t *s) { int bufSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); char *buf = new char[bufSize]; WideCharToMultiByte(CP_UTF8, 0, s, -1, buf, bufSize, NULL, NULL); wprintf(L"%S", buf); delete[] buf; return stream; } ostream &operator-(ostream &stream, const wstring &s) { stream - s.c_str(); return stream; } 

我已经使用Visual Studio 2010validation了一个解决scheme。通过此MSDN文章和MSDN博客文章 。 诀窍是对_setmode(..., _O_U16TEXT)的模糊调用。

解:

 #include <iostream> #include <io.h> #include <fcntl.h> int wmain(int argc, wchar_t* argv[]) { _setmode(_fileno(stdout), _O_U16TEXT); std::wcout << L"Testing unicode -- English -- Ελληνικά -- Español." << std::endl; } 

截图:

控制台中的Unicode

wcout必须具有与CRT不同的区域设置。 这是如何修复的:

 int _tmain(int argc, _TCHAR* argv[]) { char* locale = setlocale(LC_ALL, "English"); // Get the CRT's current locale. std::locale lollocale(locale); setlocale(LC_ALL, locale); // Restore the CRT. std::wcout.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT. std::wcout << L"¡Hola!"; std::cin.get(); return 0; } 

我只是testing它,它显示string在这里绝对好。

SetConsoleCP()和chcp不一样!

采取这个程序片段:

 SetConsoleCP(65001) // 65001 = UTF-8 static const char s[]="tränenüberströmt™\n"; DWORD slen=lstrlen(s); WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),s,slen,&slen,NULL); 

源代码必须保存为没有 BOM(字节顺序标记;签名)的UTF-8。 然后,Microsoft编译器cl.exe按原样采用UTF-8string。
如果此代码 BOM一起保存,则cl.exe会将string转码为ANSI(即CP1252),这与CP65001(= UTF-8)不匹配。

将显示字体更改为Lucidia控制台 ,否则UTF-8输出将不起作用。

  • types: chcp
  • 答案: 850
  • types: test.exe
  • 答: tr├ñnen├╝berstr├ÂmtÔäó
  • types: chcp
  • 答案: 65001 – 此设置已由SetConsoleCP()更改,但没有任何效果。
  • types: chcp 65001
  • types: test.exe
  • 答: tränenüberströmt™ – 现在一切OK。

testing:德语Windows XP SP3

我不认为有一个简单的答案。 看看控制台代码页和SetConsoleCP函数 ,你似乎需要为你要输出的字符集设置一个合适的代码页。

接下来我想从Pythonstreamunicode到Windows控制台,这是我需要做的最低限度:

  • 您应该将控制台字体设置为覆盖unicode符号的字体。 没有广泛的select:控制台属性>字体> Lucida控制台
  • 您应该更改当前的控制台代码页:在控制台中运行chcp 65001或使用C ++代码中的相应方法
  • 使用WriteConsoleW写入控制台

在Windows控制台上查看关于java unicode的互动文章

另外,在这种情况下,你不能写入默认的sys.stdout,你需要用os.write(1,binarystring)替代它,或者直接调用WriteConsoleW的包装器。 看起来像在C ++中,你将需要做同样的事情。

首先,对不起,我可能没有所需的字体,所以我还不能testing它。

这东西看起来有点可疑

 // the following is said to be working SetConsoleOutputCP(CP_UTF8); // output is in UTF8 wchar_t s[] = L"èéøÞǽлљΣæča"; int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); char* m = new char[bufferSize]; WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL); wprintf(L"%S", m); // <-- upper case %S in wprintf() is used for MultiByte/utf-8 // lower case %s in wprintf() is used for WideChar printf("%s", m); // <-- does this work as well? try it to verify my assumption 

 // the following is said to have problem SetConsoleOutputCP(CP_UTF8); utf8_locale = locale(old_locale, new boost::program_options::detail::utf8_codecvt_facet()); wcout.imbue(utf8_locale); wcout << L"¡Hola!" << endl; // <-- you are passing wide char. // have you tried passing the multibyte equivalent by converting to utf8 first? int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); char* m = new char[bufferSize]; WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL); cout << m << endl; 

关于什么

 // without setting locale to UTF8, you pass WideChars wcout << L"¡Hola!" << endl; // set locale to UTF8 and use cout SetConsoleOutputCP(CP_UTF8); cout << utf8_encoded_by_converting_using_WideCharToMultiByte << endl; 

我有一个类似的问题, 在Windows中输出Unicode到控制台使用C ++,包含在运行程序之前需要在控制台中执行chcp 65001的gem。

编程方式可能有一些方法,但我不知道它是什么。

在Windows控制台中正确显示西欧字符

长话短说:

  1. 使用chcp来查找哪个代码页适合您。 就我而言,西欧是chcp 28591
  2. 可选地使其成为默认值: REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 28591

发现的历史

我有一个类似的问题,与Java。 这只是表面上的,因为它涉及到发送到控制台的日志行; 但还是很烦人

我们的Java应用程序的输出应该是UTF-8,并且在eclipse的控制台中正确显示。 但在Windows控制台,它只是显示ASCII的箱子字符: Inicializaci├│nart├¡culos而不是Inicializaciónartículos

我偶然发现了一个相关的问题,并混合了一些答案,以find适合我的解决scheme。 解决方法是更改​​控制台使用的代码页, 使用支持UNICODE的字体(如consolaslucida console )。 您可以在Windows cosole的系统菜单中select的字体:

  1. 通过启动控制台
    1. Win + R然后键入cmd并点击Return键。
    2. 点击Win键,然后inputcmd然后return键。
  2. 打开系统菜单
    1. 点击左上angular的图标
    2. Alt + Space组合键
  3. 然后select“默认”来更改所有后续控制台窗口的行为
  4. 点击“字体”标签
  5. selectConsolasLucida console
  6. 点击OK

关于代码页,对于一次性的情况,你可以用命令chcp ,然后你必须调查哪一个代码页对你的字符集是正确的。 几个答案build议UTF-8代码页,这是65001,但该代码页不适用于我的西class牙字符。

另一个答案build议批处理脚本交互式地从列表中select你想要的代码页。 在那里,我find了我需要的ISO-8859-1代码页:28591。所以你可以执行

 chcp 28591 

每次执行您的应用程序之前。 您可以在代码页标识符MSDN页面中检查哪个代码页适合您。

还有一个答案指出如何坚持选定的代码页作为您的Windows控制台的默认值。 它涉及到更改registry,因此请考虑自己警告您可能会使用此解决scheme来阻止您的计算机。

 REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 28591 

这将HKCU \ Consoleregistry项中的28591数据创build28591值。 而这对我来说是有用的。

请注意,HKCU(“HKEY_CURRENT_USER”)仅适用于当前用户。 如果你想改变它在该计算机中的所有用户,你需要使用regedit实用程序,并find/创build相应的Console密钥(可能你将不得不在HKEY_USERS\.DEFAULT内创build一个Console密钥)