c++ - wcin.imbue 和 UTF-8

标签 c++ utf-8 g++ locale clang++

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

但是,如果我使用经典语言环境并将 UTF8 语言环境注入(inject) wcin,则不会发生这种情况。输入要么完全失败,要么每个单独的字节独立地转换为 wchar_t。

使用 clang++ 和 libc++,无论是设置全局语言环境还是在 wcin 中注入(inject)语言环境都不起作用。

#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++ - wcin.imbue 和 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32438942/

相关文章:

c++ - 从指针 vector 中删除元素并释放之前通过新运算符分配的动态内存?

c++ - 具有来自类层次结构的参数的多态函数

c++ - CUDA 简单数组搜索 - 共享内存

java - Base64编码: Illegal base64 character 3c

c++ - 查找导致 undefined reference 错误的源代码行

c++ - 在 g++ 中与 .so 链接导致 undefined reference

c++ - 我正在使用哪个版本的C++?

c++ - 在 QT Creator 中构建时强制重新链接

当#include<stack> 和#include<queue> 时,C++ 程序不会编译

python - Base64 解码图像的 Rails API ASCII 转换错误