在带有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,所以无法测试这种行为,抱歉.