C++ UTF-8 vs cpp案例需要解释
我有64位Windows 7上的Microsoft Visual Studio 2010。(在项目属性中,“字符集”设置为“未设置”,但每个设置都会导致相同的输出。) 源代码:C++ UTF-8 vs cpp案例需要解释,c++,visual-studio,utf-8,C++,Visual Studio,Utf 8,我有64位Windows 7上的Microsoft Visual Studio 2010。(在项目属性中,“字符集”设置为“未设置”,但每个设置都会导致相同的输出。) 源代码: using namespace std; char const charTest[] = "árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP\n"; cout << charTest; printf(charTest); if(set_codepa
using namespace std;
char const charTest[] = "árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP\n";
cout << charTest;
printf(charTest);
if(set_codepage()) // SetConsoleOutputCP(CP_UTF8); // *1
cerr << "DEBUG: set_codepage(): OK" << endl;
else
cerr << "DEBUG: set_codepage(): FAIL" << endl;
cout << charTest;
printf(charTest);
这背后的解释是什么?我可以要求cout
以printf
的身份工作吗
附件
许多人说Windows控制台根本不支持UTF-8字符。我是匈牙利人,我的窗口设置为英语(日期格式除外,它们设置为匈牙利语),西里尔字母仍然正确显示在匈牙利字母旁边:
(我的默认控制台代码页是CP852)在Windows上,单字节字符串通常被解释为ASCII码,或者一些256字符的代码页。这意味着您将无法获得真正的unicode支持
简短的回答是:使用宽字符串(例如,
L“árvíztűr…”
-注意L)然后写入wcout
,而不是cout
。Windows通常将宽字符串(Windows上的2个字节)解释为UTF-16(或至少是一个封闭变量)在Windows上总是使用宽字符串来避免编码问题。 < P>这里的区别是C++运行库和C库是如何处理系统区域的。
要使用std::cout获得相同的结果,您可以尝试方法和
但UTF-8和C++的主要问题描述为
C++03提供了两种字符串文字。第一种文字包含在双引号中,生成以null结尾的const char类型数组。第二种文字定义为L“,生成以空结尾的const wchar\u t类型数组,其中wchar\u t是宽字符。这两种文字类型都不支持UTF-8、UTF-16或任何其他类型的Unicode编码的字符串文字
所以无论如何都是实现特定的,因此是不可移植的,因为非标准的C++输出流可以理解UTF-8。
< P>首先Windows控制台不支持UTF-8(代码页65001,为了测试这个打开的UTF-8编码文件,它在控制台中用记事本保存,并且您将在控制台中看到垃圾数据),所以为了检查您的输出,您应该将其重定向到一个文件或类似的文件,并从中检查结果(myapp>test.txt) C/C++char[]中的第二个字符序列可以按照程序员的意愿进行任意解释,但UTF-8是一种编码unicode字符集的特殊协议,因此(在C++11之外)无法编写字符序列和用UTF8编码的字符,因为我会说char p[3]=“اب”
,但若编译器想用UTF-8编码,它需要5个字节,而不是3个字节。所以你应该使用一些理解UTF-8的东西
我建议使用带有宽字符串常量的boost::locale::conv::utf_to_utf
。比如说
std::string sUTF8 = boost::locale::conv::utf_to_utf(L"árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP\n");
std::cout << sUTF8; // or printf( "%s", sUTF8.c_str() );
std::string sUTF8=boost::locale::conv::utf_to_utf(L“rvíztűrőtükörf rógépޏrv ztŰrŐtÜkÖrf rÓgÉn”);
就我所知,命令行似乎与UTF-8配合使用
一种能够显示UTF-8字符的字体
在命令行(chcp 65001)中设置正确的代码页不确定此代码页是否支持完整的UTF-8字符,但它似乎是可用的最佳代码页
检查一下,然后
[编辑]在我签入PowerShell后,实际上65001
实际上是UTF-8
PS C:\Users\forcewill> chcp 65001
Active code page: 65001
PS C:\Users\forcewill> [Console]::OutputEncoding
BodyName : utf-8
EncodingName : Unicode (UTF-8)
HeaderName : utf-8
WebName : utf-8
WindowsCodePage : 1200
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : True
CodePage : 65001
您可以使用PowerShell,它比旧的cmd.exe强大得多
Edit:
关于使用cout如果我们在visual studio中讨论,正确的答案是更详细的解释,可以找到visual studio中的最佳实践可能与@HansPassant重复的内容我不相信是相同的。它似乎相关,但没有明确解释cout
和printf
之间的区别。我还应该写一个codevt
方面来告诉cout
不要转换任何东西吗?我希望,应该有一种更简单的方法……wcout在内部将Unicode转换为CP_ACP,然后再转换回Unicode,这样wcout实际上不支持Unicode,这难道不是问题吗?是Windows控制台输出无法与UTF-8一起工作(它不是控制台本身的有效代码页)。上面的C++层就是不做聪明的事情。正如我所说,main.cpp
是一个UTF-8文件,我可以在屏幕上正确地键入它。控制台完全了解UTF-8,并在发出chcp 65001
命令后正确处理它。我不理解您评论中的投票。@notin列出main.cpp
的编码对控制台显示的内容绝对没有影响。我清楚地记得,CP\u UTF8
仅可用于MultiByteToWideChar
和WideCharToMultiByte
,但除了论坛帖子之外,我找不到其他引用。我尝试过,事实上,更改代码页是可行的(一旦你设置了一个适当的字体,就是VisualStudio在用Unicode选项编译时所支持的宽的支持,并且当使用C++的宽特性时,它是一个16字节的编码,叫做UCS2。我认为它与UTF16字符二进制兼容,只需要前15位。它是固定长度的,所以它不能代表任何东西。需要那些没有外部信息的额外字符(系统设置、区域设置或其他)。另请参阅:streams支持的编码是实现定义的。在我的Linux计算机上,默认的iostream与utf8配合使用效果很好。可能他可以在windows上使用某些设置或API调用来获得相同的结果。我迫不及待地要等到许多C++11实现获得建议的字符串文本,如u8、U和U。我使用inter这将使我们的生活变得更加轻松。您可以在上找到一个处理UTF-8的内置语言环境,如示例所示,或者您可以找到一种使用codecvt的方法_
PS C:\Users\forcewill> chcp 65001
Active code page: 65001
PS C:\Users\forcewill> [Console]::OutputEncoding
BodyName : utf-8
EncodingName : Unicode (UTF-8)
HeaderName : utf-8
WebName : utf-8
WindowsCodePage : 1200
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : True
CodePage : 65001