【发布时间】:2015-12-03 00:36:52
【问题描述】:
在使用 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,不是任何单字节编码)。
现场演示:onetwo(我无法使用在线编译器重现其他行为)。
这符合标准吗?难道我不能不考虑全局语言环境而改用imbue 吗?
是否应将所描述的任何一种行为归类为实现错误?
【问题讨论】:
-
这里的“clang++”是什么意思?编译器无关紧要,因为这完全取决于标准库(C 和 C++ 部分)和机器上安装的语言环境数据。您是否同时检查了 libstdc++ 和 libc++,或者只使用两个编译器检查了 libstdc++ 两次?
-
@JonathanWakely 你是对的,我应该说“libstdc++ 和 libc++”。我想我确实将 libc++ 与 clang++ 一起使用,但我现在无法检查。我一拿到我的机器就会仔细检查和更新。
-
好的,那么我想知道这个问题是否是
wcin的基本限制,因为从UTF-8八位字节到wchar_t的转换是由stdio层完成的,它使用全局语言环境不是流的。但它可能只是 libstdc++ 中的一个错误(也可能是 libc++),我不确定。天真地,我也希望您使用imbue能够正常工作。 -
@JonathanWakely 我不确定如何通过 stdio 进行转换。 fstream 实现使用
fread不应该做任何翻译。 -
@JonathanWakely 事实证明,使用 libc++ neither 分支工作。我会相应地更新问题。
标签: c++ utf-8 g++ locale clang++