我如何从C上的Windows ++控制台应用程序打印UTF-8(How do I print UTF

2019-06-21 13:44发布

对于与Visual Studio 2008英文版Windows编译一个C ++控制台应用程序(XP,Vista或Windows 7)。 是否可以打印到控制台并正确显示UTF-8使用的cout或wcout编码的日语?

Answer 1:

在Windows控制台使用OEM代码页 ,默认情况下显示输出。

要更改代码页转换为Unicode输入chcp 65001在控制台,或尝试使用编程方式更改代码页SetConsoleOutputCP

请注意,你可能要在控制台的字体更改为一个有在Unicode范围字形。



Answer 2:

下面是MVP迈克尔·卡普兰的文章介绍了如何正确输出UTF-16通过控制台。 你可以你的UTF-8转换为UTF-16和输出。



Answer 3:

我从来没有真正尝试设置控制台代码页为UTF8(不知道为什么它是行不通的......控制台可以处理其它的多字节代码的页面就好了),但也有一对夫妇的功能看达:SetConsoleCP和SetConsoleOutputCP。

你可能还需要确保您使用的是控制台的字体,能够显示你的角色的。 还有的SetCurrentConsoleFontEx功能,但它仅适用于Vista和上面。

希望帮助。



Answer 4:

这应该工作:

#include <cstdio>
#include <windows.h>

#pragma execution_character_set( "utf-8" )

int main()
{
    SetConsoleOutputCP( 65001 );
    printf( "Testing unicode -- English -- Ελληνικά -- Español -- Русский. aäbcdefghijklmnoöpqrsßtuüvwxyz\n" );
}

不知道这是否会影响什么,但源文件保存为Unicode(UTF-8具有签名) -文件 代码页65001 - > 高级保存选项...。

项目 - > 属性 - > 配置属性 - > 常规 - > 字符集设置为使用Unicode字符集

有人说,你需要控制台字体更改为Lucida Console,但在我的身边则显示两者索拉龙力控制台



Answer 5:

On app start console set to default OEM437 CP. I was trying to output Unicode text to stdout, where console was switch to UTF8 translation _setmode(_fileno(stdout), _O_U8TEXT); and still had no luck on the screen even with Lucida TT font. If console was redirected to file, correct UTF8 file were created.

Finally I was lucky. I have added single line "info.FontFamily = FF_DONTCARE;" and it is working now. Hope this help for you.

void SetLucidaFont()
{
    HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_FONT_INFOEX info;
    memset(&info, 0, sizeof(CONSOLE_FONT_INFOEX));
    info.cbSize = sizeof(CONSOLE_FONT_INFOEX);              // prevents err=87 below
    if (GetCurrentConsoleFontEx(StdOut, FALSE, &info))
    {
        info.FontFamily   = FF_DONTCARE;
        info.dwFontSize.X = 0;  // leave X as zero
        info.dwFontSize.Y = 14;
        info.FontWeight   = 400;
        _tcscpy_s(info.FaceName, L"Lucida Console");
        if (SetCurrentConsoleFontEx(StdOut, FALSE, &info))
        {
        }
    }
}


Answer 6:

只是为了更多的信息:

“ANSI”指的是Windows-125X,用于Win32应用程序,而“OEM”指的是由控制台/ MS-DOS的应用程序所使用的代码的页面。
当前活动的代码的页面可以与功能GetOEMCP()和GetACP()进行检索。

为了输出正确的东西到控制台,您应该:

  1. 确保当前OEM代码页支持您要输出的字符
    (如果必要的话,可以使用SetConsoleOutputCP正确设置它)

  2. 从目前的ANSI代码(win32)中控制台OEM代码页转换字符串

下面是一些公用事业这样做:

// Convert a UTF-16 string (16-bit) to an OEM string (8-bit) 
#define UNICODEtoOEM(str)   WCHARtoCHAR(str, CP_OEMCP)

// Convert an OEM string (8-bit) to a UTF-16 string (16-bit) 
#define OEMtoUNICODE(str)   CHARtoWCHAR(str, CP_OEMCP)

// Convert an ANSI string (8-bit) to a UTF-16 string (16-bit) 
#define ANSItoUNICODE(str)  CHARtoWCHAR(str, CP_ACP)

// Convert a UTF-16 string (16-bit) to an ANSI string (8-bit)
#define UNICODEtoANSI(str)  WCHARtoCHAR(str, CP_ACP)


/* Convert a single/multi-byte string to a UTF-16 string (16-bit).
 We take advantage of the MultiByteToWideChar function that allows to specify the charset of the input string.
*/
LPWSTR CHARtoWCHAR(LPSTR str, UINT codePage) {
    size_t len = strlen(str) + 1;
    int size_needed = MultiByteToWideChar(codePage, 0, str, len, NULL, 0);
    LPWSTR wstr = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * size_needed);
    MultiByteToWideChar(codePage, 0, str, len, wstr, size_needed);
    return wstr;
}


/* Convert a UTF-16 string (16-bit) to a single/multi-byte string.
 We take advantage of the WideCharToMultiByte function that allows to specify the charset of the output string.
*/
LPSTR WCHARtoCHAR(LPWSTR wstr, UINT codePage) {
    size_t len = wcslen(wstr) + 1;
    int size_needed = WideCharToMultiByte(codePage, 0, wstr, len, NULL, 0, NULL, NULL);
    LPSTR str = (LPSTR) LocalAlloc(LPTR, sizeof(CHAR) * size_needed );
    WideCharToMultiByte(codePage, 0, wstr, len, str, size_needed, NULL, NULL);
    return str;
}


Answer 7:

在控制台,输入chcp 65001的代码页更改为UTF-8。



文章来源: How do I print UTF-8 from c++ console application on Windows