简体   繁体   English

为什么std :: codecvt <wchar_t, char, mbstate_t> 不能按定义工作?

[英]Why does std::codecvt<wchar_t, char, mbstate_t> not work as defined?

#include <iostream>

using namespace std;

void f1()
{
    wcout.imbue(locale("chs"));
    wcout << L"您" << endl;
}

void f2()
{
    locale loc(wcout.getloc(), new codecvt<wchar_t, char, mbstate_t>());

    wcout.imbue(loc);
    wcout << L"好" << endl;
}

int main()
{
    f1(); // OK
    f2(); // Error. There is no output as expected.
}

According to cplusplus.com 's online documentation: 根据cplusplus.com的在线文档:

codecvt<wchar_t,char,mbstate_t>: 

    converts between native wide and narrow character sets.

This program is compiled with VC++, and runs on Windows. 该程序使用VC ++编译,并在Windows上运行。

In this program, the internal character set is UCS-2, which is defined by the VC++ compiler; 在此程序中,内部字符集为UCS-2,由VC ++编译器定义; the external character set, ie the narrow character set, is GBK (a Chinese character set) in console environment. 在控制台环境中,外部字符集(即窄字符集)为GBK(中文字符集)。 If the documentation is true, then wcout can convert the unicode string from UCS-2 to GBK as f1() does; 如果文档是正确的,则wcout可以像f1()一样将Unicode字符串从UCS-2转换为GBK。 however, it does not. 但是,事实并非如此。 Why? 为什么?

You've default-constructed an std::codecvt , with no particular conversion rules. 您已经默认构造了std::codecvt ,没有特定的转换规则。 It has no way of knowing that you want GBK and not GB18030 or UTF-8. 它无法知道您要GBK,而不是GB18030或UTF-8。

Ways to get a codecvt that converts wchar_t to GBK: 获取将wchar_t转换为GBK的codecvt的方法:

  • Construct an std::locale for GBK just use that with your stream, no need to pull out a facet 为GBK构造一个std::locale只需将其与流一起使用,无需拉出构面

     wcout.imbue(std::locale("")); // this uses the current user settings, wcout.imbue(std::locale("zn_CN.gbk")); // or name the locale explicitly, // by whatever name Windows calls it 
  • Construct the facet directly with std::codecvt_byname 直接使用std::codecvt_byname构造构面

     wcout.imbue(std::locale(wcout.getloc(), new std::codecvt_byname("zh_CN.gbk")); // explict name 
  • Write your own conversion routine and derive from std::codecvt , so you could use it with 编写自己的转换例程并从std::codecvt ,因此可以将其与

     wcout.imbue(std::locale(wcout.getloc(), new yourcodecvt); 

Windows support for C++ locales is very poor, though, WinAPI may have a more appropriate conversion function. Windows对C ++语言环境的支持非常差,但是WinAPI可能具有更合适的转换功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM