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

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

本文关键字:不能按 gt 定义 工作 mbstate char codecvt wchar 为什么 std lt      更新时间:2023-10-16
#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.
}

根据cplusplus.com的在线文档:

codecvt<wchar_t,char,mbstate_t>: 
    converts between native wide and narrow character sets.

该程序是用VC++编译的,并在Windows上运行。

在这个程序中,内部字符集是

UCS-2,由VC++编译器定义;外部字符集,即窄字符集,在控制台环境中是GBK(中文字符集)。如果文档为 true,那么wcout可以像f1()一样将 unicode 字符串从 UCS-2 转换为 GBK;但是,事实并非如此。为什么?

您默认构造了一个std::codecvt,没有特定的转换规则。它无法知道你想要GBK而不是GB18030或UTF-8。

获取将wchar_t转换为 GBK 的编解码器的方法:

  • 为 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
    
  • 使用std::codecvt_byname直接构造分面

    wcout.imbue(std::locale(wcout.getloc(),
                new std::codecvt_byname("zh_CN.gbk")); // explict name
    
  • 编写自己的转换例程并从std::codecvt派生,以便您可以将其与

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

Windows对C++语言环境的支持非常差,但是WinAPI可能具有更合适的转换功能。