C++ UTF-8 vs cpp案例需要解释

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

我有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_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