2009-09-03 38 views
16

Đối với ứng dụng giao diện điều khiển C++ được biên dịch bằng Visual Studio 2008 trên Windows tiếng Anh (XP, Vista hoặc 7). Có thể in ra bàn điều khiển và hiển thị chính xác UTF-8 được mã hóa tiếng Nhật bằng cout hoặc wcout không?Làm cách nào để in UTF-8 từ ứng dụng giao diện C++ trên Windows

+2

Có một chủ đề thú vị tại cplusplus.com: UTF-8 ở dấu nhắc lệnh (console) http://www.cplusplus.com/forum/windows/9797/ – anno

+0

** Người mới: ** [Kiểm tra câu trả lời của tôi ở đây] (http://stackoverflow.com/a/40337240/3258851) về cách sử dụng unicode - và kiểm tra [câu trả lời này] (http://stackoverflow.com/a/26479960/ 3258851) về việc thay đổi phông chữ giao diện điều khiển. –

Trả lời

0

Trong bảng điều khiển, nhập chcp 65001 để thay đổi trang mã thành mã UTF-8.

7

Bàn điều khiển Windows sử dụng OEM code page theo mặc định để hiển thị đầu ra.

Để thay đổi trang mã thành Unicode, hãy nhập chcp 65001 trong bảng điều khiển hoặc cố gắng thay đổi trang mã theo lập trình với SetConsoleOutputCP.

Lưu ý rằng bạn có thể phải thay đổi phông chữ của bảng điều khiển thành phông chữ có glyph trong phạm vi unicode.

+4

Lưu ý rằng có rất nhiều lỗi với UTF-8 làm mã. Hầu hết là WONTFIX. – Deduplicator

4

Tôi chưa bao giờ thử cài đặt trang bảng điều khiển thành UTF8 (không chắc chắn lý do tại sao nó không hoạt động ... bàn điều khiển có thể xử lý các trang mã nhiều byte khác), nhưng có một vài các hàm cần tra cứu: SetConsoleCP và SetConsoleOutputCP.

Có thể bạn cũng sẽ cần đảm bảo rằng bạn đang sử dụng phông chữ bảng điều khiển có khả năng hiển thị các ký tự của bạn. Có chức năng SetCurrentConsoleFontEx, nhưng nó chỉ khả dụng trên Vista trở lên.

Hy vọng điều đó sẽ hữu ích.

+2

Thử dùng phông chữ Lucida Console. – anno

4

Here's an article from MVP Michael Kaplan về cách xuất UTF-16 chính xác thông qua bảng điều khiển. Bạn có thể chuyển đổi UTF-8 thành UTF-16 và xuất ra.

+2

Một quan sát: Michael Kaplan không phải là MVP. Tôi không biết anh ta có bao giờ. Anh ta là một nhân viên của Microsoft cho các lứa tuổi (nhân viên của Microsoft không đủ điều kiện cho chương trình MVP). –

+0

Liên kết này mang đến _Resource Not Found_. – Salvador

+0

Kể từ năm 2016-08-09, liên kết chuyển hướng đến http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html nhưng có tài liệu hiện tại (có lẽ là những gì ban đầu có tại siao2.com). –

1

Trên bảng điều khiển bắt đầu ứng dụng được đặt thành OEM437 CP mặc định. Tôi đã cố gắng để xuất văn bản Unicode để stdout, nơi giao diện điều khiển được chuyển sang UTF8 dịch _setmode (_fileno (stdout), _O_U8TEXT); và vẫn không có may mắn trên màn hình ngay cả với phông chữ Lucida TT. Nếu bàn điều khiển được chuyển hướng đến tệp, hãy chỉnh sửa tệp UTF8.

Cuối cùng tôi đã may mắn. Tôi đã thêm một dòng "info.FontFamily = FF_DONTCARE;" và nó hiện đang hoạt động. Hy vọng sự trợ giúp này dành cho bạn.

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

này nên làm việc:

#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"); 
} 

Không biết nếu nó ảnh hưởng đến bất cứ điều gì, nhưng tập tin nguồn được lưu lại dưới dạng Unicode (UTF-8 có chữ ký) - bảng mã 65001 tại FILE ->Tùy chọn Lưu nâng cao ....

Dự án ->Thuộc tính ->Configuration Properties ->chung ->Character Set được thiết lập để Sử dụng Unicode Character Set.

Một số người nói bạn cần thay đổi giao diện điều khiển phông chữ để Lucida Console, nhưng đứng về phía tôi nó được hiển thị với cả ConsolasLucida Console.

+0

Sử dụng trang mã 1252 (latin 1), những công việc này. – someonewithpc

1

Chỉ cần biết thêm thông tin:

'ANSI' đề cập đến cửa sổ-125x, được sử dụng cho các ứng dụng win32 khi 'OEM' đề cập đến trang mã được sử dụng bởi các ứng dụng giao diện điều khiển/MS-DOS.
Các trang mã hiện tại có thể được truy xuất với các hàm GetOEMCP() và GetACP().

Để ra một cái gì đó một cách chính xác để giao diện điều khiển, bạn nên:

  1. đảm bảo dòng điện trang mã OEM hỗ trợ các ký tự mà bạn muốn đầu ra
    (nếu cần thiết, sử dụng SetConsoleOutputCP để thiết lập nó đúng)

  2. chuyển đổi chuỗi từ mã ANSI hiện tại (win32) để trang mã giao diện điều khiển OEM

Dưới đây là một số tiện ích để làm như vậy:

// 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; 
} 
Các vấn đề liên quan