代码之家  ›  专栏  ›  技术社区  ›  Paul Dixon

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

  •  18
  • Paul Dixon  · 技术社区  · 15 年前

    7 回复  |  直到 15 年前
        1
  •  8
  •   dtb    15 年前

    Windows控制台使用 OEM code page

    要将代码页更改为Unicode,请输入 chcp 65001 SetConsoleOutputCP .

    请注意,您可能必须将控制台的字体更改为具有unicode范围内的标志符号的字体。

        3
  •  4
  •   ijprest    15 年前

    我从来没有尝试过将控制台代码页设置为UTF8(不知道为什么它不能工作。。。控制台可以很好地处理其他多字节代码页),但是有两个函数需要查找:SetConsoleCP和SetConsoleOutputCP。

    您可能还需要确保使用的是能够显示字符的控制台字体。这是 SetCurrentConsoleFontEx 功能,但它只在Vista和更高版本上可用。

        4
  •  3
  •   Slaus    9 年前

    这应该有效:

    #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 文件 -> .

    项目 属性 -> -> 总则 -> 设置为 .

    有人说你需要把控制台字体改成 露西达控制台 ,但在我这边,它和 孔索拉 露西达控制台

        5
  •  1
  •   adspx5    9 年前

    应用程序启动控制台设置为默认OEM437 CP。 我试图将Unicode文本输出到stdout,控制台被切换到UTF8转换设置模式(stdout,stdout),即使使用Lucida TT字体,在屏幕上仍然没有成功。 如果控制台被重定向到文件,则会创建正确的UTF8文件。

    最后我很幸运。我已经添加了单行“info.fontfamine=FF\u 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))
            {
            }
        }
    }
    
        6
  •  1
  •   Cédric Françoys    9 年前

    仅供参考:


    可以使用函数getoecp()和GetACP()检索当前活动的代码页。

    为了将某些内容正确输出到控制台,您应该:


    1. (如有必要,请使用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;
    }
    
        7
  •  0
  •   Alan Haggai Alavi    15 年前

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