在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; }
截图:
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控制台中正确显示西欧字符
长话短说:
- 使用
chcp
来查找哪个代码页适合您。 就我而言,西欧是chcp 28591
。 - 可选地使其成为默认值:
REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 28591
发现的历史
我有一个类似的问题,与Java。 这只是表面上的,因为它涉及到发送到控制台的日志行; 但还是很烦人
我们的Java应用程序的输出应该是UTF-8,并且在eclipse的控制台中正确显示。 但在Windows控制台,它只是显示ASCII的箱子字符: Inicializaci├│n
和art├¡culos
而不是Inicialización
和artículos
。
我偶然发现了一个相关的问题,并混合了一些答案,以find适合我的解决scheme。 解决方法是更改控制台使用的代码页, 并使用支持UNICODE的字体(如consolas
或lucida console
)。 您可以在Windows cosole的系统菜单中select的字体:
- 通过启动控制台
-
Win + R
然后键入cmd
并点击Return
键。 - 点击
Win
键,然后inputcmd
然后return
键。
-
- 打开系统菜单
- 点击左上angular的图标
- 按
Alt + Space
组合键
- 然后select“默认”来更改所有后续控制台窗口的行为
- 点击“字体”标签
- select
Consolas
或Lucida console
- 点击
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
密钥)