在使用g++的Linux上,如果我设置了utf8全局语言环境,则wcin
会将UTF-8正确地转码为内部wchar_t编码。
但是,如果我使用经典语言环境并将UTF8语言环境注入(inject)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)本地化语言环境和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/