如何从Windows上的C++控制台应用程序打印UTF-8

wvyml7n5  于 2023-03-20  发布在  Windows
关注(0)|答案(9)|浏览(346)

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

kyvafyod

kyvafyod1#

这应该行得通:

#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控制台 *,但在我这边它同时显示有 Consolas 和 *Lucida控制台 *。

rfbsl7qr

rfbsl7qr2#

默认情况下,Windows控制台使用OEM code page显示输出。
要将代码页更改为Unicode,请在控制台中输入**chcp 65001**,或尝试使用SetConsoleOutputCP以编程方式更改代码页。
注意,您可能需要将控制台的字体更改为具有Unicode范围内字形的字体。

6uxekuva

6uxekuva3#

Here's an article from MVP Michael Kaplan关于如何通过控制台正确输出UTF-16。你可以将你的UTF-8转换成UTF-16并输出。

uqzxnwby

uqzxnwby4#

我从来没有尝试过将控制台代码页设置为UTF8(不知道为什么它不起作用...控制台可以很好地处理其他多字节代码页),但是有几个函数可以查找:设置控制台CP和设置控制台输出CP。
你可能还需要确保你使用的控制台字体能够显示你的字符。有SetCurrentConsoleFontEx函数,但它只在Vista和更高版本中可用。
希望能有所帮助。

rkue9o1l

rkue9o1l5#

在应用程序启动控制台上,设置为默认OEM 437 CP。我试图将Unicode文本输出到标准输出,其中控制台切换到UTF8翻译_setmode(_fileno(stdout),_O_U8TEXT);即使使用Lucida TT字体,在屏幕上仍然没有运气。如果控制台被重定向到文件,则创建了正确的UTF8文件。
最后我很幸运,我添加了一行“info.FontFamily = FF_DONTCARE;“而且现在正在工作,希望这对你有帮助。

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))
        {
        }
    }
}
mznpcxlj

mznpcxlj6#

仅供参考:
“ANSI”指的是windows-125 x,用于win32应用程序,而“OEM”指的是控制台/MS-DOS应用程序使用的代码页。
当前激活的代码页可通过函数GetOEMCP()和GetACP()检索。
为了将某些内容正确输出到控制台,您应该:
1.确保当前OEM代码页支持要输出的字符
(if必要时,使用SetConsoleOutputCP进行正确设置)
1.将字符串从当前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;
}
odopli94

odopli947#

对于任何需要从文件读取UTF-8并打印到控制台的人,可以尝试wifstream,即使在Visual Studio调试器中也能正确显示UTF-8单词(我正在处理繁体中文),从this post

#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;
zysjyyx4

zysjyyx48#

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

yiytaume

yiytaume9#

您可以使用system调用:

#include <stdlib.h>
#include <stdio.h>

int main() {
    system("chcp 65001");
    printf("%s\n", "中文");
}

相关问题