Vấn đề là bảng điều khiển sử dụng các trang mã khác với phần còn lại của hệ thống. Ví dụ, các hệ thống Windows thông thường được thiết lập cho châu Mỹ và Tây Âu sử dụng CP1252, nhưng bàn điều khiển ở những khu vực đó sử dụng CP437 hoặc CP850.
Bạn có thể đặt trang mã đầu ra của bảng điều khiển để khớp với mã hóa bạn đang sử dụng hoặc bạn có thể chuyển đổi các chuỗi để khớp với trang mã đầu ra của bảng điều khiển.
Đặt bảng mã điều khiển đầu ra:
SetConsoleOutputCP(GetACP()); // GetACP() returns the system codepage.
std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".";
Hoặc là một trong nhiều cách để chuyển đổi giữa các bảng mã (cái này đòi hỏi VS2010 hoặc cao hơn):
#include <codecvt> // for wstring_convert
#include <locale> // for codecvt_byname
#include <iostream>
int main() {
typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> codecvt;
// the following relies on non-standard behavior, codecvt destructors are supposed to be protected and unusable here, but VC++ doesn't complain.
std::wstring_convert<codecvt> cp1252(new codecvt(".1252"));
std::wstring_convert<codecvt> cp850(new codecvt(".850"));
std::cout << cp850.to_bytes(cp1252.from_bytes("...été trouvée à...\n")).c_str();
}
Ví dụ thứ hai giả định bạn làm trong thực tế cần phải chuyển đổi giữa 1252 và 850. Bạn có thể sử dụng hàm GetOEMCP() để tìm ra trang mã đích thực tế và mã nguồn thực sự phụ thuộc vào những gì bạn sử dụng cho mã nguồn thay vì kết quả của GetACP() trên máy chạy chương trình.
Cũng lưu ý rằng chương trình này dựa vào một thứ không được đảm bảo bởi tiêu chuẩn: mã hóa wchar_t được chia sẻ giữa các ngôn ngữ. Điều này đúng trên hầu hết các nền tảng — thường là một số mã hóa Unicode được sử dụng cho wchar_t ở tất cả các ngôn ngữ — nhưng không phải tất cả.
Lý tưởng nhất là bạn chỉ có thể sử dụng UTF-8 ở khắp mọi nơi và sau đây sẽ làm việc tốt, vì nó hiện trên các nền tảng khác những ngày này:
#include <iostream>
int main() {
std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".\n";
}
Đáng tiếc là Windows không thể hỗ trợ UTF-8 theo cách này mà không phải từ bỏ UTF-16 như mã hóa wchar_t và áp dụng một byte 4 byte, hoặc vi phạm các yêu cầu của tiêu chuẩn và phá vỡ các chương trình phù hợp tiêu chuẩn.
Tôi cho rằng bạn đang sử dụng Windows? –
Có, tôi sẽ sửa đổi câu hỏi của tôi để chỉ định. – jmegaffin
@Boreal: Đảm bảo rằng bạn chuyển đổi chuỗi được lưu trữ trong tệp thành Unicode UTF-16 (có nghĩa là mã hóa Unicode sẽ được sử dụng bên trong ứng dụng Windows). Bạn có thể làm điều đó đọc chuỗi từ tệp của bạn và sau đó sử dụng 'MultiByteToWideChar()' API (hoặc trình trợ giúp chuyển đổi ATL 'CA2W') để chuyển đổi từ mã hóa cụ thể sang UTF-16. Sau đó, để in một chuỗi Unicode thành bàn điều khiển, bạn chỉ cần khởi tạo giao diện điều khiển bằng '_setmode (_fileno (stdout), _O_U16TEXT);', và sau đó bạn có thể sử dụng 'wprintf()' hoặc 'std :: wcout'. Xem câu trả lời của tôi để biết thêm chi tiết và liên kết. –