Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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++ 在Windows控制台应用程序中输出unicode字符串_C++_Unicode_Iostream_Windows Console - Fatal编程技术网

C++ 在Windows控制台应用程序中输出unicode字符串

C++ 在Windows控制台应用程序中输出unicode字符串,c++,unicode,iostream,windows-console,C++,Unicode,Iostream,Windows Console,嗨,我正试图用iostreams将unicode字符串输出到控制台,但失败了 我发现了这个:这个片段很有效 SetConsoleOutputCP(CP_UTF8); wchar_t s[] = L"èéøÞǽлљΣæča"; int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL); char* m = new char[bufferSize]; WideCharToMultiByte(CP_UTF

嗨,我正试图用iostreams将unicode字符串输出到控制台,但失败了

我发现了这个:这个片段很有效

SetConsoleOutputCP(CP_UTF8);
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m);
但是,我没有找到任何方法可以使用iostreams正确输出unicode。有什么建议吗

这不起作用:

SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl;

我认为没有一个简单的答案。查看,您似乎需要为要输出的字符集设置适当的代码页。

wcout的区域设置必须与CRT不同。下面是如何修复的:

int _tmain(int argc, _TCHAR* argv[])
{
    char* locale = setlocale(LC_ALL, "English"); // Get the CRT's current locale.
    std::locale lollocale(locale);
    setlocale(LC_ALL, locale); // Restore the CRT.
    std::wcout.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT.
    std::wcout << L"¡Hola!";
    std::cin.get();
    return 0;
}
int-tmain(int-argc,_-TCHAR*argv[]
{
char*locale=setlocale(LC_ALL,“English”);//获取CRT的当前区域设置。
std::locale lollage(locale);
setlocale(LC_ALL,locale);//恢复CRT。
std::wcout.imbue(lollocale);//现在将std::wcout设置为我们从CRT获得的区域设置。

std::wcout最近,我想将unicode从Python流式传输到windows控制台,下面是我需要做的最低要求:

  • 您应该将console字体设置为覆盖unicode符号的字体。没有广泛的选择:console属性>字体>Lucida console
  • 您应该更改当前控制台代码页:在控制台中运行<代码> CHCP 65001 <代码>,或者使用C++代码< /LI>中的相应方法
  • 使用WriteConsoleW写入控制台
浏览一篇关于


此外,在Python中,你不能对默认的SysStdUn进行写写,在这种情况下,你需要用OS来代替它。写(1,二进制字符串)或直接调用Wrror EndoSeCo中的包装器。看起来像C++一样,你也需要这样做。首先,对不起,我可能没有字体,所以我不能测试它。 这里有点可疑

// the following is said to be working
SetConsoleOutputCP(CP_UTF8); // output is in UTF8
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m); // <-- upper case %S in wprintf() is used for MultiByte/utf-8
                   //     lower case %s in wprintf() is used for WideChar
printf("%s", m); // <-- does this work as well? try it to verify my assumption
//据说以下功能正在工作
SetConsoleOutputCP(CP_UTF8);//输出为UTF8格式
wchar_t s[]=L“èèèèèèèèèèèèèèè;
int bufferSize=WideCharToMultiByte(CP_UTF8,0,s,-1,NULL,0,NULL,NULL);
char*m=新字符[bufferSize];
宽图表多字节(CP_UTF8,0,s,-1,m,bufferSize,NULL,NULL);
wprintf(L“%S”,m);//我有一个类似的问题,包含在运行程序之前需要在控制台中执行的gem
chcp 65001


可能有一些方法可以通过编程实现,但我不知道它是什么。

我在这里使用Visual Studio 2010验证了一个解决方案。通过这个和。诀窍是对
\u setmode(…,\u O\u U16TEXT)

解决方案:

#包括
#包括
#包括
int wmain(int argc,wchar_t*argv[])
{
_setmode(_fileno(stdout),_O_16text);
std::wcoutSetConsoleCP()和chcp不一样

以这个程序片段为例:

SetConsoleCP(65001)  // 65001 = UTF-8
static const char s[]="tränenüberströmt™\n";
DWORD slen=lstrlen(s);
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),s,slen,&slen,NULL);
源代码必须保存为不带BOM(字节顺序标记;签名)的UTF-8。然后,Microsoft编译器cl.exe按原样接受UTF-8字符串。
如果此代码与BOM一起保存,cl.exe会将字符串转码为ANSI(即CP1252),这与CP65001(=UTF-8)不匹配。 将显示字体更改为Lucidia Console,否则UTF-8输出将无法工作

  • 类型:
    chcp
  • 回答:
    850
  • 类型:
    test.exe
  • 回答:
    tr├尼宁├╝贝尔斯特├Ôäó山
  • 类型:
    chcp
  • 回答:
    65001
    -此设置已通过
    SetConsoleCP()
    更改,但没有任何有用的效果。
  • 类型:
    chcp 65001
  • 类型:
    test.exe
  • 回答:
    tränenüberströmt™-现在一切正常。
    
测试:德语Windows XP SP3

在Windows控制台中正确显示西欧字符 长话短说:
  • 使用
    chcp
    查找适合您的代码页。在我的例子中,它是西欧的
    chcp 28591
  • 可选择将其设为默认值:
    REG ADD HKCU\Console/v CodePage/t REG\u DWORD/d 28591
  • 发现历史 Java也有类似的问题,这只是表面现象,因为它涉及到发送到控制台的日志行;但仍然很烦人

    Java应用程序的输出应该是UTF-8格式,并且在eclipse的控制台中正确显示。但在windows控制台中,它只显示ASCII框绘图字符:
    Inicializaci├│n
    艺术├“culos
    而不是
    Inicialización
    artículos

    我偶然发现并混合了一些答案,找到了适合我的解决方案。解决方案是使用支持UNICODE的字体(如
    ConsoleAS
    lucida console
    )更改控制台使用的代码页。您可以在Windows cosole的系统菜单中选择的字体:

  • 通过以下任一方法启动控制台:
    • Win+R
      然后键入
      cmd
      并点击
      Return
    • Win
      键,键入
      cmd
      ,然后按
      return
  • 通过以下任一方法打开系统菜单:
    • 单击左上角的图标
    • 点击
      Alt+Space
      组合键
  • 然后选择“Default”以更改所有后续控制台窗口的行为
  • 单击“字体”选项卡
  • 选择
    Consolas
    Lucida console
  • 单击
    OK
  • 关于代码页,对于一次性情况,您可以使用命令
    chcp
    完成,然后您必须调查哪个代码页适合您的字符集。几个答案建议使用UTF-8代码页,即65001,但该代码页不适合我的西班牙语字符

    建议使用批处理脚本以交互方式从列表中选择所需的代码页。在那里,我找到了我需要的ISO-8859-1代码页:28591。因此,您可以执行

    chcp 28591
    
    在每次执行应用程序之前。您可以在中检查哪个代码页适合您

    // without setting locale to UTF8, you pass WideChars wcout << L"¡Hola!" << endl; // set locale to UTF8 and use cout SetConsoleOutputCP(CP_UTF8); cout << utf8_encoded_by_converting_using_WideCharToMultiByte << endl;

    SetConsoleCP(65001)  // 65001 = UTF-8
    static const char s[]="tränenüberströmt™\n";
    DWORD slen=lstrlen(s);
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),s,slen,&slen,NULL);
    
    chcp 28591
    
    REG ADD HKCU\Console /v CodePage /t REG_DWORD /d 28591
    
    const char* umessage = "Hello!\nПривет!\nПривіт!\nΧαιρετίσματα!\nHelló!\nHallå!\n";
    
    ...
    #include <console.hpp>
    #include <ios>
    ...
    
    std::ostream& cout = io::console::out_stream();
    cout << umessage
    << 1234567890ull << '\n'
    << 123456.78e+09 << '\n'
    << 12356.789e+10L << '\n'
    << std::hex << 0xCAFEBABE
    << std::endl;
    
    int wmain(int argc, wchar_t* argv[])
    
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);
    
    CONSOLE_FONT_INFOEX fontInfo;
    // ... configure fontInfo
    SetCurrentConsoleFontEx(hConsole, false, &fontInfo);
    
    char* a = setlocale(LC_ALL, "chinese");
    
    std::wcout << L"你好" << std::endl;
    
    #include <Windows.h>
    #include <iostream>
    #include <io.h>
    #include <fcntl.h>
    #include <locale.h>
    #include <wincon.h>
    
    int wmain(int argc, wchar_t* argv[])
    {
        SetConsoleTitle(L"My Console Window - 你好");
        HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
        char* a = setlocale(LC_ALL, "chinese");
        SetConsoleOutputCP(CP_UTF8);
        SetConsoleCP(CP_UTF8);
    
        CONSOLE_FONT_INFOEX fontInfo;
        fontInfo.cbSize = sizeof(fontInfo);
        fontInfo.FontFamily = 54;
        fontInfo.FontWeight = 400;
        fontInfo.nFont = 0;
        const wchar_t myFont[] = L"KaiTi";
        fontInfo.dwFontSize = { 18, 41 };
        std::copy(myFont, myFont + (sizeof(myFont) / sizeof(wchar_t)), fontInfo.FaceName);
    
        SetCurrentConsoleFontEx(hConsole, false, &fontInfo);
    
        std::wcout << L"Hello World!" << std::endl;
        std::wcout << L"你好!" << std::endl;
        return 0;
    }
    
    #if defined (_WIN32) 
    #define WINDOWSLIB 1
    
    #elif defined (__ANDROID__) || defined(ANDROID)//Android
    #define ANDROIDLIB 1
    
    #elif defined (__APPLE__)//iOS, Mac OS
    #define MACOSLIB 1
    
    #elif defined (__LINUX__) || defined(__gnu_linux__) || defined(__linux__)//_Ubuntu - Fedora - Centos - RedHat
    #define LINUXLIB 1
    #endif
    
    #include <locale>
    #include <iostream>
    #include <string>
    #ifdef WINDOWSLIB
    #include <Windows.h>
    #endif
    
    using namespace std::literals::string_literals;
    
    // Convert std::wstring to std::string
    std::string WidestringToString(const std::wstring& wstr, const std::string& locale)
    {
        if (wstr.empty())
        {
            return std::string();
        }
        size_t pos;
        size_t begin = 0;
        std::string ret;
        size_t  size;
    #ifdef WINDOWSLIB
        _locale_t lc = _create_locale(LC_ALL, locale.c_str());
        pos = wstr.find(static_cast<wchar_t>(0), begin);
        while (pos != std::wstring::npos && begin < wstr.length())
        {
            std::wstring segment = std::wstring(&wstr[begin], pos - begin);
            _wcstombs_s_l(&size, nullptr, 0, &segment[0], _TRUNCATE, lc);
            std::string converted = std::string(size, 0);
            _wcstombs_s_l(&size, &converted[0], size, &segment[0], _TRUNCATE, lc);
            ret.append(converted);
            begin = pos + 1;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
        }
        if (begin <= wstr.length()) {
            std::wstring segment = std::wstring(&wstr[begin], wstr.length() - begin);
            _wcstombs_s_l(&size, nullptr, 0, &segment[0], _TRUNCATE, lc);
            std::string converted = std::string(size, 0);
            _wcstombs_s_l(&size, &converted[0], size, &segment[0], _TRUNCATE, lc);
            converted.resize(size - 1);
            ret.append(converted);
        }
        _free_locale(lc);
    #elif defined LINUXLIB
        std::string currentLocale = setlocale(LC_ALL, nullptr);
        setlocale(LC_ALL, locale.c_str());
        pos = wstr.find(static_cast<wchar_t>(0), begin);
        while (pos != std::wstring::npos && begin < wstr.length())
        {
            std::wstring segment = std::wstring(&wstr[begin], pos - begin);
            size = wcstombs(nullptr, segment.c_str(), 0);
            std::string converted = std::string(size, 0);
            wcstombs(&converted[0], segment.c_str(), converted.size());
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
        }
        if (begin <= wstr.length()) {
            std::wstring segment = std::wstring(&wstr[begin], wstr.length() - begin);
            size = wcstombs(nullptr, segment.c_str(), 0);
            std::string converted = std::string(size, 0);
            wcstombs(&converted[0], segment.c_str(), converted.size());
            ret.append(converted);
        }
        setlocale(LC_ALL, currentLocale.c_str());
    #elif defined MACOSLIB
    #endif
    
        return ret;
    }
    
    // Convert std::string to std::wstring
    std::wstring StringToWideString(const std::string& str, const std::string& locale)
    {
        if (str.empty())
        {
            return std::wstring();
        }
    
        size_t pos;
        size_t begin = 0;
        std::wstring ret;
        size_t  size;
    
    #ifdef WINDOWSLIB
        _locale_t lc = _create_locale(LC_ALL, locale.c_str());
        pos = str.find(static_cast<char>(0), begin);
        while (pos != std::string::npos) {
            std::string segment = std::string(&str[begin], pos - begin);
            std::wstring converted = std::wstring(segment.size() + 1, 0);
            _mbstowcs_s_l(&size, &converted[0], converted.size(), &segment[0], _TRUNCATE, lc);
            converted.resize(size - 1);
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = str.find(static_cast<char>(0), begin);
        }
        if (begin < str.length()) {
            std::string segment = std::string(&str[begin], str.length() - begin);
            std::wstring converted = std::wstring(segment.size() + 1, 0);
            _mbstowcs_s_l(&size, &converted[0], converted.size(), &segment[0], _TRUNCATE, lc);
            converted.resize(size - 1);
            ret.append(converted);
        }
        _free_locale(lc);
    #elif defined LINUXLIB
        std::string currentLocale = setlocale(LC_ALL, nullptr);
        setlocale(LC_ALL, locale.c_str());
        pos = str.find(static_cast<char>(0), begin);
        while (pos != std::string::npos) {
            std::string segment = std::string(&str[begin], pos - begin);
            std::wstring converted = std::wstring(segment.size(), 0);
            size = mbstowcs(&converted[0], &segment[0], converted.size());
            converted.resize(size);
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = str.find(static_cast<char>(0), begin);
        }
        if (begin < str.length()) {
            std::string segment = std::string(&str[begin], str.length() - begin);
            std::wstring converted = std::wstring(segment.size(), 0);
            size = mbstowcs(&converted[0], &segment[0], converted.size());
            converted.resize(size);
            ret.append(converted);
        }
        setlocale(LC_ALL, currentLocale.c_str());
    #elif defined MACOSLIB
    #endif
    
        return ret;
    }
    
    std::wstring x = L"\0\001日本ABC\0DE\0F\0GYou can use the open-source {fmt} library to portably print Unicode text, including on Windows, for example:

    #include <fmt/core.h>
    
    int main() {
      fmt::print("èéøÞǽлљΣæča");
    }
    
    èéøÞǽлљΣæča
    
    ├и├й├╕├Ю╟╜╨╗╤Щ╬г├ж─Нa
    
    #include <boost/nowide/iostream.hpp>
    #include <char8_t-remediation.h>
    
    int main()
    {
        using boost::nowide::cout;
    
        cout << U8("¡Hola!") << std::endl;
    }
    
    #include <sstream>
    #include <fstream>
    #include <codecvt>
    
    std::wstring readFile(const char* filename)
    {
        std::wifstream wif(filename);
        wif.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
        std::wstringstream wss;
        wss << wif.rdbuf();
        return wss.str();
    }
    
    //  usage
    std::wstring wstr2;
    wstr2 = readFile("C:\\yourUtf8File.txt");
    wcout << wstr2;