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

时间:2009-09-03 01:25:40

标签: c++ utf-8 console-application

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

8 个答案:

答案 0 :(得分:8)

Windows控制台默认使用OEM code page来显示输出。

要将代码页更改为Unicode,请在控制台中输入 chcp 65001 ,或尝试使用SetConsoleOutputCP以编程方式更改代码页。

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

答案 1 :(得分:6)

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

答案 2 :(得分:4)

我从来没有尝试过将控制台代码页设置为UTF8(不知道为什么它不起作用......控制台可以处理其他多字节代码页就好了),但有几个要查找的函数:SetConsoleCP和SetConsoleOutputCP。

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

希望有所帮助。

答案 3 :(得分:2)

这应该有效:

#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 文件 - &gt; 高级保存选项...

项目 - &gt; 属性 - &gt; 配置属性 - &gt; 一般 - &gt; 字符集设置为使用Unicode字符集

有人说您需要将控制台字体更改为 Lucida控制台,但在我这边,它会同时显示 Consolas Lucida控制台

答案 4 :(得分:1)

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

最后我很幸运。我添加了单行&#34; info.FontFamily = FF_DONTCARE;&#34;它现在正在运作。 希望对你有所帮助。

private class CallDestination extends AsyncTask<String, Void, JSONObject>{
        protected JSONObject doInBackground(String...url){

            String MYURL = "";

            if(url[0].isEmpty()){
                MYURL = "http://thevisitapp.com/api/destinations/read?identifiers=10011";
            } else{
                MYURL = "http://thevisitapp.com/api/destinations/read?identifiers=" + url[0];
            }
            //TODO make this dynamic as it's passed in from other activity through intent


            HttpRequest request = new HttpRequest();
            return request.getJSONFromUrl(MYURL);
}

答案 5 :(得分:1)

仅供参考:

&#39; ANSI&#39;指的是windows-125x,用于win32应用程序,而OEM&#39;指控制台/ MS-DOS应用程序使用的代码页 可以使用GetOEMCP()和GetACP()函数检索当前活动代码页。

为了正确地向控制台输出内容,您应该:

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

  2. 将字符串从当前ANSI代码(win32)转换为控制台OEM代码页

  3. 以下是一些实用程序:

    // 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;
    }
    

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

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