c – wcin.imbue和UTF-8

在带有g的 linux上,如果我设置了utf8全局语言环境,那么wcin正确地将UTF-8转码为内部wchar_t编码.

但是,如果我使用经典语言环境并将UTF8语言环境灌输到wcin中,则不会发生这种情况.输入完全失败,或者每个字节独立转换为wchar_t.

使用clang和libc,既不设置全局语言环境也不在wcin中使用语言环境.

#include <iostream>
#include <locale>
#include <string>

using namespace std;

int main() {
    if(true)        
        // this works with g++,but not with clang++/libc++
        locale::global(locale("C.UTF-8"));
    else
        // this doesn't work with either implementation
        wcin.imbue(locale("C.UTF-8"));
    wstring s;
    wcin >> s;
    cout << s.length() << " " << (s == L"áéú");
    return 0;
}

输入流仅包含áéú字符. (它们是UTF-8,而不是任何单字节编码).

现场演示:one two(我无法重现在线编译器的其他行为).

这是符合标准的吗?我不应该单独留下全局区域设置并使用imbue吗?

是否应将任何描述的行为归类为实施错误

解决方法

首先你应该使用wcout和wcin.

现在您有两种可能的解决方案:

1)通过使用取消激活iostream和cstdio流的同步

ios_base::sync_with_stdio(false);

请注意,这应该是第一次调用,否则行为取决于实现.

int main() {

   ios_base::sync_with_stdio(false);
   wcin.imbue(locale("C.UTF-8"));

   wstring s;
   wcin >> s;
   wcout << s.length() << " " << (s == L"áéú");
   return 0;
}

2)本地化locale和wcout:

int main() {

   std::setlocale(LC_ALL,"C.UTF-8");
   wcout.imbue(locale("C.UTF-8"));

    wstring s;
    wcin >> s;
    wcout << s.length() << " " << (s == L"áéú");
    return 0;
}

使用ideone测试它们,工作正常.我没有clang / libc,所以无法测试这种行为,抱歉.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...