如何将C++ wstring UTF-8字符打印到Mac OS或Unix终端?

Fra*_*ank 1 c++ unicode macos

我该如何打印std::wstring使用std::wcout

我尝试以下,这是推荐这里,但它仅适用于印刷本¡Hola!,但不是这个??:

#include <iostream>
#include <clocale>

int main(int argc, char* argv[])
{
  char* locale = setlocale(LC_ALL, ""); 
  std::cout << "locale: " << locale << std::endl; // "C" for me
  std::locale lollocale(locale);
  setlocale(LC_ALL, locale); 
  std::wcout.imbue(lollocale);
  std::wcout << L"¡Hola!" << std::endl; // ok
  std::wcout << L"??" << std::endl;    // empty :(
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

以下(这里推荐)也不打印日文字符:

#include <stdio.h>
#include <string>
#include <locale>
#include <iostream>

using namespace std;

int main()
{

        std::locale::global(std::locale(""));
        wstring japan = L"??";
        wstring message = L"Welcome! Japan is ";

        message += japan;

        wprintf(message.c_str());
        wcout << message << endl;
}
Run Code Online (Sandbox Code Playgroud)

所有这些都在Mac OS 10.6.8上.使用g ++ 4.2.1,使用终端2.1.2.

终端可以一般地显示字符,例如,当我cat是源代码时.此外,此命令工作正常cout << "??" << std::endl;,但我需要打印wstring.

我的$LANG是这样的:

$ echo $LANG 
en_US.UTF-8
Run Code Online (Sandbox Code Playgroud)

bam*_*s53 6

打印wstring的方法是将其转换为基于UTF-8字符串的字符串.严重的是,wchar_t在Windows之外或其他各种平台库之一是毫无意义的,不幸的是它们在使用wchar_t之前已经明白了它是什么坏主意.

// move to clang and libc++ then
#include <codecvt>

int main(){
    std::wstring_convert<std::codecvt_utf8<wchar_t>,wchar_t> convert; // converts between UTF-8 and UCS-4 (given sizeof(wchar_t)==4)
    std:wstring s = L"??";
    std::cout << convert.to_bytes(s);
}
Run Code Online (Sandbox Code Playgroud)

只是为了解释你所展示的代码出了什么问题;

char* locale = setlocale(LC_ALL, ""); 
std::cout << "locale: " << locale << std::endl; // "C" for me
Run Code Online (Sandbox Code Playgroud)

此处的区域设置字符串是应用更改后的区域设置名称.既然你说你得到"C"就意味着你正在使用"C"语言环境.通常会有一个像"en_US.UTF-8"这样的名称,但无论出于何种原因,您的环境都没有正确设置.您显示$LANG已正确设置但可能其他一个区域设置环境变量设置不同.

在任何情况下,您都使用"C"语言环境,只需支持基本字符集.我相信OS X你会得到的行为是任何char会直接转换为相同的wchar_t值,只有wchar_t支持的范围内的值char才会转换回来.这实际上与使用基于ISO 8859-1的语言环境相同,因此日语字符不起作用.


如果你真的坚持让这个基于语言环境的东西工作,那么你需要得到一个合适的语言环境,一个使用UTF-8的语言环境.您可以找出您的环境有什么问题,也可以使用不可移植的显式语言环境名称.

std::wcout.imbue(std::locale("en_US.UTF-8"));
std::wcout << L"¡Hola!\n";
std::wcout << L"??\n";
Run Code Online (Sandbox Code Playgroud)

此外,如果您使用的是libstdc ++,您应该知道它在OS X上不能正确支持语言环境.您必须使用libc ++才能使OS X的语言环境名称(例如"en_US.UTF-8")正常工作.


Dan*_*lKO 5

根据 libstdc++ 上的多个错误报告(例如http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35353),C 运行时和 libstdc++ 之间存在令人讨厌的交互,并且似乎没有人急于尝试修复它,可能是因为 utf-8 在大多数情况下“正常工作”。

该错误报告提到了两种解决方法,使用ios_base::sync_with_stdio(false)locale::global(...)