Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何打印C++;wstring UTF-8字符到Mac OS或Unix终端?_C++_Macos_Unicode - Fatal编程技术网

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

C++ 如何打印C++;wstring UTF-8字符到Mac OS或Unix终端?,c++,macos,unicode,C++,Macos,Unicode,如何使用std::wcout打印std::wstring 我尝试了以下建议,但它仅适用于打印此“Hola但不是此日本: #include <iostream> #include <clocale> int main(int argc, char* argv[]) { char* locale = setlocale(LC_ALL, ""); std::cout << "locale: " << locale << std::

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

我尝试了以下建议,但它仅适用于打印此
“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;
}

根据libstdc++上的多个bug报告(例如),在C运行时和libstdc++之间存在令人讨厌的交互,似乎没有人急于尝试修复它,可能是因为utf-8在大多数情况下“只起作用”


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

根据libstdc++上的多个错误报告(例如),在C运行时和libstdc++之间存在令人讨厌的交互,似乎没有人愿意尝试修复它,可能是因为utf-8“刚刚工作”在大多数情况下


bug报告提到了两种解决方法,使用
ios\u base::sync\u with\u stdio(false)
locale::global(…)
打印wstring的方法是将其转换为基于UTF-8字符的字符串。严重地脱离了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);
}

另外,如果您使用libstdc++,您应该知道它在OS X上不支持正确的区域设置。您必须使用libc++才能使OS X的区域设置名称(例如,“en_US.UTF-8”)正常工作。

打印wstring的方法是将其转换为基于UTF-8字符的字符串。严重地脱离了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);
}

此外,如果您使用的是libstdc++,您应该知道它在OS X上不支持正确的区域设置。您必须使用libc++才能使OS X的区域设置名称(例如,“en_US.UTF-8”)正常工作。

使用nowide库以最简单的方式转换为UTF-8。然后,使用常规printf。

使用nowide库以最简单的方式转换为UTF-8。然后,使用常规printf。

默认编码:

  • Windows UTF-16
  • Linux UTF-8
  • MacOS UTF-8
我的解决方案步骤,包括空字符\0(避免截断)。不使用windows.h标题上的函数:

  • 添加宏以检测平台。 Windows/Linux及其他
  • 创建函数,将std::wstring转换为std::string,并将std::string反向转换为std::wstring
  • 创建打印功能
  • 打印std::string/std::wstring
  • 检查。原始字符串后缀

    Linux代码。使用std::cout直接打印std::string,Linux上的默认编码是UTF-8,不需要额外的函数

    在Windows上,如果需要打印unicode。我们可以使用std::wstring打印unicode字符

    最后在Windows上。您需要在控制台中对unicode字符提供强大且完整的视图支持。 我推荐

    QA

    • 使用VC++在Microsoft Visual Studio 2019上测试;std=c++17。(Windows项目)
    • 使用Clang编译器在repl.it上进行测试;std=c++17
    Q.为什么不使用
    头函数和类?
    A.反对在VC++上不可能构建,但在g++上没有问题。我更喜欢零警告和头痛

    Q.std::wstring是跨平台的?
    A.No.std::wstring使用wchar\t元素。在Windows wchar\U t上,大小为2字节,每个字符以UTF-16单位存储,如果字符大于U+FFFF,则字符以两个UTF-16单位(2个wchar\U t元素)表示,称为代理项对。在Linux上,wchar\u t大小为4字节,每个字符存储在一个wchar\u t元素中,不需要代理项对。检查

    Q.std::string是跨平台的吗?
    是的。string使用char元素。在大多数编译器中,保证字符类型的字节大小相同。字符类型大小为1字节。检查

    完整示例代码

    
    #包括
    #包括
    #包括
    #包括
    //窗户
    #如果(_WIN32)
    #包括
    #包括
    #定义WINDOWS\u平台1
    #定义DLLCALL STDCALL
    #定义DLLIMPORT _declspec(DLLIMPORT)
    #定义DLLEXPORT\u declspec(DLLEXPORT)
    #定义DLLPRIVATE
    #定义NOMINMAX
    //EMSCRIPTEN
    #已定义的elif(_EMSCRIPTEN__;)
    #包括
    #包括
    #包括
    #包括
    #定义EMSCRIPTEN_平台1
    #定义DLLCALL
    #定义DLLIMPORT
    #定义DLLEXPORT属性(可见性(“默认”))
    #定义DLLPRIVATE属性(可见性(“隐藏”))
    //LINUX-Ubuntu、Fedora、Centos、Debian、RedHat
    #elif(uuLinux_uu124; u124; uuGNU_124; u124; 124; u124; 124; 124; 124; LINUX | | LINUX)
    #定义LINUX_平台1
    #包括
    #包括
    #定义DLLCALL-CDECL
    #定义DLLIMPORT
    #定义DLLEXPORT属性(可见性(“默认”))
    #定义DLLPRIVATE属性(可见性(“隐藏”))
    #定义CoTaskMemAlloc(p)malloc(p)
    #定义CoTaskMemFree(p)free(p)
    //安卓
    #elif(安卓安卓)
    #定义ANDROID_平台1
    #定义DLLCALL
    #定义DLLIMPORT
    #定义DLLEXPORT属性(可见性(“默认”))
    #定义DLLPRIVATE属性(可见性(“隐藏”))
    //马科斯
    #已定义的elif(_苹果公司)
    #包括
    #包括
    #定义DLLCALL
    #定义DLLIMPORT
    #定义DLLEXPORT属性(可见性(“默认”))
    #定义DLLPRIVATE属性(可见性(“隐藏”))
    #包括“TargetConditionals.h”
    #如果目标IPHONE和目标IPHONE模拟器
    #定义IOS_模拟器_平台1
    #elif TARGET_OS_IPHONE
    #定义IOS_平台1
    #elif TARGET_OS_MAC
    #定义MACOS_平台1
    #否则
    #恩迪夫
    #恩迪夫
    typedef std::string字符串;
    类型定义标准::wstring wstring;
    #定义空字符串u8“s
    #定义空字符串
    使用名称空间std::literals::string_literals;
    类字符串
    {
    公众:
    静态字符串宽字符串缩放(常量wstr和wstr)
    {
    如果(wstr.empty
    
    // 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);
    }
    
    char* locale = setlocale(LC_ALL, ""); 
    std::cout << "locale: " << locale << std::endl; // "C" for me
    
    std::wcout.imbue(std::locale("en_US.UTF-8"));
    std::wcout << L"¡Hola!\n";
    std::wcout << L"日本\n";