c++ How to display L"أَبْجَدِيَّة عَرَبِيَّة‎中文" using wcout?

ifsvaxew  于 2022-12-30  发布在  其他
关注(0)|答案(6)|浏览(1781)

我想使用wcout显示阿拉伯文和中文混合的消息。
下面的代码是正确的:

#include <iostream>

using namespace std;

int main()
{
    wcout.imbue(locale("chs"));
    wcout << L"中文"; // OK
}

但是,下面的代码不起作用:

#include <iostream>

using namespace std;

int main()
{
    wcout.imbue(locale(/* What to place here ??? */));
    wcout << L"أَبْجَدِيَّة عَرَبِيَّة‎中文"; // Output nothing. VC++ 2012 on Win7 x64
    // Why does the main advantage of unicode not apply here?
}

我认为在采用unicode之后,代码页的概念应该被弃用。

Q1. wout显示此类文本的机制是什么?
问题2:作为基于Unicode的操作系统,为什么Windows不支持在其控制台窗口中输出Unicode字符?

u2nhd7ah

u2nhd7ah1#

默认情况下,CRT会将所有输出到文件的内容都视为ANSI格式。您可以在程序开始时使用这一行来更改

_setmode(_fileno(stdout), _O_WTEXT);

http://www.siao2.com/2008/03/18/8306597.aspx的良好参考
仅供参考,双向语言支持在大多数命令提示符中是有限的,据我所知,这是导致这个问题的限制。为什么不支持它是我无法回答的问题。

ryhaxcpt

ryhaxcpt2#

不能使用标准C++工具便携地打印宽字符串。
相反,您可以使用the open-source {fmt} library以便携方式打印Unicode文本。例如(https://godbolt.org/z/nccb6j):

#include <fmt/core.h>

int main() {
  fmt::print("أَبْجَدِيَّة عَرَبِيَّة‎中文");
}

印刷品

أَبْجَدِيَّة عَرَبِيَّة‎中文

这需要使用MSVC中的/utf-8编译器选项进行编译。
为了进行比较,写入Linux上的wcouthttps://godbolt.org/z/h9WKsY):

std::wcout << L"أَبْجَدِيَّة عَرَبِيَّة‎中文";

印刷品

???????????? ?????????????

除非您将全局区域设置切换为eidogg. en_US.utf8。类似的问题存在于Windows上,没有标准的方法来修复它(您必须使用非标准的CRT函数或Windows API)。

    • 免责声明**:我是{fmt}的作者。
r9f1avp5

r9f1avp53#

我刚看了这篇文章
“总结一下...
如果使用Visual C++,则不能使用UTF-8将文本打印到std::cout。
如果您还想了解,请阅读这篇关于如何使wcout和cout工作的超长文章,但它并没有真正给予一个简单的解决方案-最后落到重新定义流缓冲区...”http://alfps.wordpress.com/2011/12/08/unicode-part-2-utf-8-stream-mode/
(from本博客http://blog.cppcms.com/post/105

njthzxwz

njthzxwz4#

你可以试试这个:
我假设你能够渲染中文文本,这意味着你有中文字体文件。
请尝试只使用阿拉伯文文本。如果您可以呈现,则表示您的系统中有阿拉伯文字体。
但是当你混合使用阿拉伯文和中文时,你需要强制选择一个同时包含两种字形的字体文件,我认为wcout选择的默认字体文件没有阿拉伯文字形。
我想你可能会得到阿拉伯语统一码盒。

fykwrbwg

fykwrbwg5#

#include <iostream>
#include <io.h>
#include <fcntl.h>

int main() {
    _setmode(_fileno(stdout), _O_U16TEXT); // or _O_WTEXT
    std::wcout << L"أَبْجَدِيَّة عَرَبِيَّة‎中文" << std::endl;
}

http://www.cplusplus.com/forum/beginner/126557/

vs3odd8k

vs3odd8k6#

在Windows上

我建议将wcout缓冲区重定向到一个文件以便于查看结果,因为Windows命令提示符无法显示某些unicode字体。

#include <iostream>
#include <fstream>                                                                                                                     

int main()
{
    std::locale myloc("en_US.UTF-8");
    std::locale::global(myloc);                                              

    std::wfilebuf wfbuf;
    wfbuf.open("result.txt", std::ios::out);
    std::wcout.rdbuf(std::addressof(wfbuf));   
                                                
    std::wcout << L"أَبْجَدِيَّة عَرَبِيَّة‎中文";   
 
    return 0;
}

在Linux上

方法1

#include <iostream>                                                                                                                        
                       
int main()
{
    std::ios::sync_with_stdio(false);// make wcout no longer depend on stdio
    std::locale myloc("en_US.UTF-8");                                           
    std::wcout.imbue(myloc);                                                    
    std::wcout << L"أَبْجَدِيَّة عَرَبِيَّة‎中文";   
 
    return 0;
}

方法2

#include <cstdio>                                                                                                                        
                       
int main()
{
    std::locale myloc("en_US.UTF-8");                                           
    std::locale::global(myloc);// can affect stdio's locale                                               
    wprintf(L"أَبْجَدِيَّة عَرَبِيَّة‎中文");  
 
    return 0;
}

方法3

#include <cstdio>                                                                                                                        
                       
int main()
{
    std::locale myloc("en_US.UTF-8");                                           
    std::locale::global(myloc);// can affect stdio's locale                                                                 
    std::wcout << L"أَبْجَدِيَّة عَرَبِيَّة‎中文";// wcout depend on stdio, it doesn't matter if wcout's locale still C locale.

    return 0;
}

相关问题