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

时间:2014-03-22 14:02:39

标签: c++ visual-c++ unicode 64-bit console-application

在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();
}

输出:

  

00007FF616443E50

我希望输出这个:

  

测试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。英语 - ???????? - Español。

设置输出CP,如下所示:SetConsoleOutputCP(CP_UTF8);

输出再次被截断:

  

测试Unicode。英语 -

1 个答案:

答案 0 :(得分:2)

使用以下内容并不能单独工作。您还必须做的是右键单击弹出的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 Panel\Appearance and Personalization\Fonts。我点击Font Settings,然后取消选中Hide fonts based on language settings。保存了选项。这将允许您编写日语和中文字符以及阿拉伯语和您想要的任何其他语言。似乎也可以使用默认的控制台字体..我必须重新启动它才能生效。不确定它是否真的适用于其他任何人..