嗨,我试图将unicode字符串输出到带有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);
Run Code Online (Sandbox Code Playgroud)
但是,我没有找到任何方法来使用iostream正确输出unicode.有什么建议?
这不起作用:
SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl;
Run Code Online (Sandbox Code Playgroud)
编辑 我找不到任何其他解决方案,而不是在流中包装此片段.希望,有人有更好的想法.
//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 = …Run Code Online (Sandbox Code Playgroud) 我还在学习C++,所以忍受我和我的草率代码.我使用的编译器是Dev C++.我希望能够使用cout将Unicode字符输出到控制台.当我尝试这样的事情时:
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
std::cout << "Blah blah blah some gibberish unicode: ??ß??\n";
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它会向控制台输出奇怪的字符,例如μA■Gg.为什么会这样做,我怎样才能展示ĐĄßĞĝ?或者Windows无法实现这一点?
关于这个问题已经有一些问题了.我认为我的问题有点不同,因为我没有实际问题,我只是在考虑学术兴趣.我知道Windows的UTF-16实现有时与Unicode标准(例如整理)相矛盾,或者更接近旧UCS-2而不是UTF-16,但我会在这里保留"UTF-16"术语,原因是简单.
背景:在Windows中,一切都是UTF-16.无论你是在处理内核,图形子系统,文件系统还是其他什么,你都要传递UTF-16字符串.Unix意义上没有语言环境或字符集.为了与中世纪版本的Windows兼容,有一个名为"codepages"的东西已经过时但仍然受到支持.AFAIK,只有一个正确且非过时的函数可以将字符串写入控制台,即WriteConsoleW采用UTF-16字符串.此外,类似的讨论也适用于输入流,我也会忽略它.
但是,我认为这代表了Windows API中的一个设计缺陷:有一个通用函数可以用来写入所有被调用的流对象(文件,管道,控制台......)WriteFile,但是这个函数是面向字节的,不是接受UTF-16字符串.文档建议使用WriteConsoleW控制台输出,这是面向文本的,和WriteFile对于其他一切,这是面向字节的.由于控制台流和文件对象都由内核对象句柄表示,并且控制台流可以重定向,因此必须为标准输出流的每次写入调用一个函数,以检查句柄是表示控制台流还是文件,从而破坏多态性.OTOH,我认为Windows在文本字符串和原始字节之间的分离(在许多其他系统中镜像,如Java或Python)在概念上优于Unix的char*方法,忽略编码并且不区分字符串和字节数组.
所以我的问题是:在这种情况下该怎么办?为什么即使在微软自己的库中也没有解决这个问题?.NET Framework和C和C++库似乎都遵循过时的代码页模型.您将如何设计Windows API或应用程序框架来规避此问题?
我认为一般问题(不容易解决)是所有库都假设所有流都是面向字节的,并在此基础上实现面向文本的流.但是,我们看到Windows在操作系统级别上确实有特殊的面向文本的流,并且库无法处理这个问题.因此,无论如何,我们必须对所有标准库进行重大更改.一种快速而肮脏的方法是将控制台视为一种特殊的面向字节的流,只接受一种编码.这仍然要求必须绕过C和C++标准库,因为它们没有实现WriteFile/ WriteConsoleWswitch.那是对的吗?