猿问

在Windows控制台应用程序中输出Unicode字符串

在Windows控制台应用程序中输出Unicode字符串

嗨,我试图将Unicode字符串输出到控制台碘流但失败了。

我发现了这个:在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);

但是,我没有找到任何方法来正确输出ioStreams的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;

编辑我找不到任何其他的解决方案,只能把这个片段包在一个流里。希望有人有更好的主意。

//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; }


PIPIONE
浏览 1502回答 3
3回答

慕无忌1623718

我在这里使用VisualStudio 2010验证了一个解决方案。通过这个MSDN文章和MSDN博客文章..诀窍是对_setmode(..., _O_U16TEXT).解决办法:#include&nbsp;<iostream>#include&nbsp;<io.h>#include&nbsp;<fcntl.h>int&nbsp;wmain(int&nbsp;argc,&nbsp;wchar_t*&nbsp;argv[]){ &nbsp;&nbsp;&nbsp;&nbsp;_setmode(_fileno(stdout),&nbsp;_O_U16TEXT); &nbsp;&nbsp;&nbsp;&nbsp;std::wcout&nbsp;<<&nbsp;L"Testing&nbsp;unicode&nbsp;--&nbsp;English&nbsp;--&nbsp;Ελληνικά&nbsp;--&nbsp;Español."&nbsp;<<&nbsp;std::endl;}

偶然的你

中文Unicode Hello World这里是中文的“你好世界”。其实只是“你好”。我在Windows 10上测试了这一点,但我认为它可能会在WindowsVista之后工作。在WindowsVista之前,如果您想要一个编程解决方案,而不是配置控制台/注册表等,这将是很困难的。如果您真的需要在Windows 7上这样做,请看这里:更改控制台字体Windows 7我不想说这是唯一的解决办法,但这才是对我有用的。提纲Unicode项目设置将控制台代码页设置为Unicode查找并使用支持要显示的字符的字体。使用要显示的语言的区域设置。使用宽字符输出,即std::wcout1项目设置我正在使用VisualStudio2017 CE。我创建了一个空白控制台应用程序。默认设置没有问题。但是,如果您遇到问题或使用了不同的ide,您可能需要检查以下内容:在项目属性中找到配置属性->General->Project Default->字符集。应该是“使用Unicode字符集”,而不是“多字节”。这将定义_UNICODE和UNICODE预处理宏给你。int&nbsp;wmain(int&nbsp;argc,&nbsp;wchar_t*&nbsp;argv[])而且我觉得我们应该用wmain功能代替main..它们都可以工作,但是在unicode环境中。wmain可能更方便。另外,我的源文件是UTF-16-le编码的,这似乎是默认的在VisualStudio 2017。2.控制台代码页这很明显。我们需要控制台中的Unicode代码页。如果要检查默认代码页,只需打开控制台并键入chcp任何争论。我们必须将它更改为65001,这是UTF-8代码页。Windows代码页标识符该代码页有一个预处理宏:CP_UTF8..我需要同时设置输入和输出代码页。当我忽略其中任何一个时,输出都是不正确的。SetConsoleOutputCP(CP_UTF8);SetConsoleCP(CP_UTF8);还可以检查这些函数的布尔值返回值。3.选择字体直到现在,我还没有找到支持每个字符的控制台字体。所以我不得不选择一个。如果您想要输出只在一种字体中部分可用,部分在另一种字体中可用的字符,那么我认为不可能找到解决方案。只有当有一种字体支持每一个字符时,才有可能。但我也没有研究如何安装字体。我认为不可能同时在同一个控制台窗口中使用两种不同的字体。如何找到兼容的字体?打开控制台,单击窗口左上方的图标,转到控制台窗口的属性。转到“字体”选项卡,选择一种字体,然后单击“确定”。然后尝试在控制台窗口中输入您的字符。重复此操作,直到找到可以使用的字体。然后记下字体的名称。此外,还可以在“属性”窗口中更改字体的大小。如果您找到满意的大小,请记下“选定字体”部分“属性”窗口中显示的大小值。它将显示宽度和高度(以像素为单位)。若要以编程方式实际设置字体,请使用:CONSOLE_FONT_INFOEX&nbsp;fontInfo;//&nbsp;...&nbsp;configure&nbsp;fontInfoSetCurrentConsoleFontEx(hConsole,&nbsp;false,&nbsp;&fontInfo);有关详细信息,请参阅本答案末尾的示例。或者在精细的手册里查一查:SetCurrentConsoleFont..此功能只存在于WindowsVista之后。4.设置地区您需要将区域设置为要打印的字符的语言区域设置。char*&nbsp;a&nbsp;=&nbsp;setlocale(LC_ALL,&nbsp;"chinese");返回值很有趣。它将包含一个字符串,用于准确描述所选的区域设置。试试看:-)我用chinese和german..更多信息:赛特5.使用宽字符输出这里没什么好说的。如果要输出宽字符,请使用以下示例:std::wcout&nbsp;<<&nbsp;L"你好"&nbsp;<<&nbsp;std::endl;哦,别忘了L宽字符的前缀!如果在源文件中键入这样的文本Unicode字符,则必须对源文件进行Unicode编码。与VisualStudio中的默认设置一样,UTF-16-le也是。或者用记事本+并将编码设置为UCS-2 LE BOM.例最后,我把所有这些放在一起作为一个例子:#include&nbsp;<Windows.h>#include&nbsp;<iostream>#include&nbsp;<io.h>#include&nbsp;<fcntl.h>#include&nbsp;<locale.h>#include&nbsp;<wincon.h>int&nbsp;wmain (int&nbsp;argc,&nbsp;wchar_t*&nbsp;argv[]){ &nbsp;&nbsp;&nbsp;&nbsp;SetConsoleTitle(L"My&nbsp;Console&nbsp;Window&nbsp;-&nbsp;你好"); &nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hConsole&nbsp;=&nbsp;GetStdHandle(STD_OUTPUT_HANDLE); &nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;a&nbsp;=&nbsp;setlocale(LC_ALL,&nbsp;"chinese"); &nbsp;&nbsp;&nbsp;&nbsp;SetConsoleOutputCP(CP_UTF8); &nbsp;&nbsp;&nbsp;&nbsp;SetConsoleCP(CP_UTF8); &nbsp;&nbsp;&nbsp;&nbsp;CONSOLE_FONT_INFOEX&nbsp;fontInfo; &nbsp;&nbsp;&nbsp;&nbsp;fontInfo.cbSize&nbsp;=&nbsp;sizeof(fontInfo); &nbsp;&nbsp;&nbsp;&nbsp;fontInfo.FontFamily&nbsp;=&nbsp;54; &nbsp;&nbsp;&nbsp;&nbsp;fontInfo.FontWeight&nbsp;=&nbsp;400; &nbsp;&nbsp;&nbsp;&nbsp;fontInfo.nFont&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;wchar_t&nbsp;myFont[]&nbsp;=&nbsp;L"KaiTi"; &nbsp;&nbsp;&nbsp;&nbsp;fontInfo.dwFontSize&nbsp;=&nbsp;{&nbsp;18,&nbsp;41&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;std::copy(myFont,&nbsp;myFont&nbsp;+&nbsp;(sizeof(myFont)&nbsp;/&nbsp;sizeof(wchar_t)),&nbsp;fontInfo.FaceName); &nbsp;&nbsp;&nbsp;&nbsp;SetCurrentConsoleFontEx(hConsole,&nbsp;false,&nbsp;&fontInfo); &nbsp;&nbsp;&nbsp;&nbsp;std::wcout&nbsp;<<&nbsp;L"Hello&nbsp;World!"&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;std::wcout&nbsp;<<&nbsp;L"你好!"&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}干杯!

慕虎7371278

wcout必须设置与CRT不同的区域设置。下面是如何解决这个问题的方法:int&nbsp;_tmain(int&nbsp;argc,&nbsp;_TCHAR*&nbsp;argv[]){ &nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;locale&nbsp;=&nbsp;setlocale(LC_ALL,&nbsp;"English");&nbsp;//&nbsp;Get&nbsp;the&nbsp;CRT's&nbsp;current&nbsp;locale. &nbsp;&nbsp;&nbsp;&nbsp;std::locale&nbsp;lollocale(locale); &nbsp;&nbsp;&nbsp;&nbsp;setlocale(LC_ALL,&nbsp;locale);&nbsp;//&nbsp;Restore&nbsp;the&nbsp;CRT. &nbsp;&nbsp;&nbsp;&nbsp;std::wcout.imbue(lollocale);&nbsp;//&nbsp;Now&nbsp;set&nbsp;the&nbsp;std::wcout&nbsp;to&nbsp;have&nbsp;the&nbsp;locale&nbsp;that&nbsp;we&nbsp;got&nbsp;from&nbsp;the&nbsp;CRT. &nbsp;&nbsp;&nbsp;&nbsp;std::wcout&nbsp;<<&nbsp;L"¡Hola!"; &nbsp;&nbsp;&nbsp;&nbsp;std::cin.get(); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}我刚刚测试了它,它显示这里的字符串非常好。
随时随地看视频慕课网APP
我要回答