将字符串流传递给unicode项目中的控制台输出

Passing a stringstream to console output in unicode project

本文关键字:项目 控制台 输出 unicode 字符串      更新时间:2023-10-16

在msvc++中,如果您创建一个新的Visual Studio控制台应用程序(x64平台,运行在Windows 8.1, x64),并将其设置为Unicode字符集,在main中使用以下代码:

int _tmain(int argc, _TCHAR* argv[])
{
    stringstream stream;
    stream << _T("Testing Unicode. English - Ελληνικά - Español.") << std::endl;
    string str = stream.str();
    std::wcout << str.c_str();
    cin.get();
}

输出如下:

00007 ff616443e50

我希望它输出如下:

测试Unicode。英文- Ελληνικά - Español.

如何做到这一点?

编辑:用wstringstream和wstring代替:

wstringstream stream; stream << _T("Testing Unicode. English - Ελληνικά - Español.") << std::endl;
wstring str = stream.str();
std::wcout << str.c_str();

输出被截断:

测试Unicode。英语- - - - - -

设置模式如下:_setmode(_fileno(stdout), _O_U16TEXT);

输出仍然是不需要的,因为不是所有的字符都被正确地呈现:

测试Unicode。中文- ????????——西班牙人。

像这样设置输出CP: SetConsoleOutputCP(CP_UTF8);

输出再次被截断:

测试Unicode。英语- - - - - -

单独使用下面的代码是不行的。您还必须做的是右键单击弹出的Visual Studio控制台。单击默认属性。点击字体选项卡,将字体设置为Lucida Consolas。那么下面的代码就可以正常运行了。没有超载的<< operator为窗口,它将无法工作。您可能还想为charwchar_t重载,或者简单地将其设置为模板重载。

如果你不喜欢超载,你可以使用_setmode(_fileno(stdout), _O_U16TEXT);_setmode(_fileno(stdout), _O_U8TEXT);为UTF16和UTF8恭顺。

// Unicode.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <sstream>
#include <iostream>
#if defined _WIN32 || defined _WIN64
    #include <Windows.h>
#else
    #include <io.h>
    #include <fcntl.h>
#endif
#if defined _WIN32 || defined _WIN64
std::ostream& operator << (std::ostream& os, const char* data)
{
    SetConsoleOutputCP(CP_UTF8);
    DWORD slen = strlen(data);
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), data, slen, &slen, nullptr);
    return os;
}
std::ostream& operator << (std::ostream& os, const std::string& data)
{
    SetConsoleOutputCP(CP_UTF8);
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), data.c_str(), data.size(), nullptr, nullptr);
    return os;
}
std::wostream& operator <<(std::wostream& os, const wchar_t* data)
{
    DWORD slen = wcslen(data);
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), data, slen, &slen, nullptr);
    return os;
}
std::wostream& operator <<(std::wostream& os, const std::wstring& data)
{
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), data.c_str(), data.size(), nullptr, nullptr);
    return os;
}
#endif
int _tmain(int argc, _TCHAR* argv[])
{
    std::wstringstream stream;
    stream << _T("Testing Unicode. English - Ελληνικά - Español.") << std::endl;
    #if !defined _WIN32 && !defined _WIN64
        _setmode(_fileno(stdout), _O_U16TEXT);
    #endif
    std::wstring str = stream.str();
    std::wcout << str;
    std::wcin.get();
    return 0;
}

在Windows上还有一个东西可以帮助渲染任何语言的字体。我发现这不是张贴在其他任何地方在网上…我导航到Control PanelAppearance and PersonalizationFonts。我点击了Font Settings,然后选中了Hide fonts based on language settings。保存选项。这将允许您编写日文和中文字符以及阿拉伯语和其他任何您想要的语言。似乎也适用于默认的控制台字体。但我必须重新启动才能生效。不确定它是否真的适用于其他人…