首页 文章

wcin.imbue和UTF-8

提问于
浏览
7

在带有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 吗?

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

1 回答

  • 2

    首先你应该使用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,所以无法测试这种行为,抱歉 .

相关问题