C++ wcin.imbue和UTF-8

C++ wcin.imbue和UTF-8,c++,utf-8,g++,locale,clang++,C++,Utf 8,G++,Locale,Clang++,在使用g++的linux上,如果我设置了utf8全局区域设置,那么wcin将UTF-8正确地转换为内部wchar\t编码 但是,如果我使用经典语言环境并将UTF8语言环境嵌入到wcin中,则不会发生这种情况。输入要么完全失败,要么每个字节独立转换为wchar\u t 使用clang++和libc++,既不设置全局区域设置,也不在wcinwork中嵌入区域设置 #include <iostream> #include <locale> #include <string

在使用g++的linux上,如果我设置了utf8全局区域设置,那么
wcin
将UTF-8正确地转换为内部wchar\t编码

但是,如果我使用经典语言环境并将UTF8语言环境嵌入到wcin中,则不会发生这种情况。输入要么完全失败,要么每个字节独立转换为wchar\u t

使用clang++和libc++,既不设置全局区域设置,也不在
wcin
work中嵌入区域设置

#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;
}
#包括
#包括
#包括
使用名称空间std;
int main(){
如果(真)
//这适用于g++,但不适用于clang++/libc++
语言环境:全局(语言环境(“C.UTF-8”);
其他的
//这两种实现都不起作用
wcin.imbue(区域设置(“C.UTF-8”);
WSTS环;
wcin>>s;

cout首先,您应该将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;
}
intmain(){
ios_base::与_stdio同步(false);
wcin.imbue(区域设置(“C.UTF-8”);
WSTS环;
wcin>>s;

WCOUT,这里的“CLAN++”是什么意思?编译器是不相关的,因为这完全取决于标准库(C和C++部件)和机器上安装的现场数据。您是否检查了LIbSTDC++和LBC+ +,或者只使用两个编译器检查LIbSTDc++ +两次?@ JoaNehanWayky,你是对的,我应该说。“libstdc++和libc++"。我想我确实将libc++与clang++一起使用,但我现在无法检查。我一到我的机器就会再次检查并更新。好的,那么我想知道问题是否是
wcin
的一个基本限制,因为从UTF-8八位字节到
wchar\u t
的转换是由stdio层完成的,它使用全局语言环境而不是stream是一个。但它可能只是libstdc++中的一个bug(也可能是libc++中的bug),我不确定。天真的我也希望你使用
imbue
能起作用。@JonathanWakely我不确定通过stdio的转换如何可能起作用。fstream实现使用
fread
,这不应该做任何翻译。@JonathanWakely结果是,对于libc++来说,两个分支都不起作用。我将相应地更新这个问题。好吗我知道ListStc++的全局设置是什么,但是为什么我们需要与STDIO不同步来激活一个区域?我在标准中找不到任何东西。Syc允许你在同一个程序中使用CUT和PrimTf。非区域C流会在与C++流同步的同时中断UTF-8编码。这就是为什么第二个解决方案使用全局S的原因。EtLoalALE。但是我不做任何C流I/O,为什么还需要unSunc?这是默认的同步流的行为,这些是微软的话,不是标准的。虽然我爱微软,就像下一个家伙一样,他们并不是完全知道他们对C++标准的严格要求。
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;
}