Bạn sẽ nhận được rất nhiều câu trả lời về các ký tự rộng. Các ký tự rộng, cụ thể là wchar_t
không bằng Unicode. Bạn có thể sử dụng chúng (với một số cạm bẫy) để lưu trữ Unicode, giống như bạn có thể unsigned char
. wchar_t
phụ thuộc rất nhiều vào hệ thống. Để trích dẫn Unicode Standard, version 5.2, chapter 5:
With the wchar_t
wide character type, ANSI/ISO C provides for inclusion of fixed-width, wide characters. ANSI/ISO C leaves the semantics of the wide character set to the specific implementation but requires that the characters from the portable C execution set correspond to their wide character equivalents by zero extension.
và
The width of wchar_t
is compiler-specific and can be as small as 8 bits. Consequently, programs that need to be portable across any C or C++ compiler should not use wchar_t
for storing Unicode text. The wchar_t
type is intended for storing compiler-defined wide characters, which may be Unicode characters in some compilers.
Vì vậy, nó thực hiện được xác định. Dưới đây là hai triển khai: Trên Linux, wchar_t
rộng 4 byte và biểu thị văn bản trong mã hóa UTF-32 (bất kể ngôn ngữ hiện tại). (Hoặc là BE hoặc LE tùy thuộc vào hệ thống của bạn, tùy theo nguồn gốc nào.) Windows, tuy nhiên, có chiều rộng 2 byte wchar_t
và đại diện cho các đơn vị mã UTF-16 với chúng. Hoàn toàn khác.
Đường dẫn tốt hơn: Tìm hiểu về ngôn ngữ, vì bạn cần biết điều đó.Ví dụ, bởi vì tôi đã thiết lập môi trường của tôi sử dụng UTF-8 (Unicode), các chương trình sau đây sẽ sử dụng Unicode:
#include <iostream>
int main()
{
setlocale(LC_ALL, "");
std::cout << "What's your name? ";
std::string name;
std::getline(std::cin, name);
std::cout << "Hello there, " << name << "." << std::endl;
return 0;
}
...
$ ./uni_test
What's your name? 佐藤 幹夫
Hello there, 佐藤 幹夫.
$ echo $LANG
en_US.UTF-8
Nhưng không có gì là Unicode về nó . Nó chỉ đọc trong các ký tự, có dạng UTF-8 vì tôi có môi trường của tôi được đặt theo cách đó. Tôi có thể dễ dàng nói "heck, tôi là một phần người Séc, chúng ta hãy sử dụng ISO-8859-2": Đột nhiên, chương trình nhận được đầu vào trong ISO-8859-2, nhưng vì nó chỉ làm lại nó, nó không thành vấn đề , chương trình sẽ vẫn hoạt động chính xác.
Bây giờ, nếu ví dụ đó đã đọc trong tên của tôi, và sau đó cố gắng viết nó ra thành một tệp XML và viết nguệch ngoạc <?xml version="1.0" encoding="UTF-8" ?>
ở trên cùng, nó sẽ đúng khi thiết bị đầu cuối của tôi là UTF-8, nhưng sai khi thiết bị đầu cuối của tôi ở ISO-8859-2. Trong trường hợp thứ hai, nó sẽ cần phải chuyển đổi nó trước khi serializing nó vào tập tin XML. (Hoặc, chỉ cần viết ISO-8859-2 làm mã hóa cho tệp XML.)
Trên nhiều hệ thống POSIX, ngôn ngữ hiện tại thường là UTF-8, vì nó cung cấp một số lợi thế cho người dùng, nhưng điều này không phải là ' t được bảo đảm. Chỉ cần xuất UTF-8 đến stdout
thường sẽ chính xác, nhưng không phải lúc nào cũng vậy. Giả sử tôi đang sử dụng ISO-8859-2: nếu bạn không biết đầu ra ISO-8859-1 "è" (0xE8
) vào thiết bị đầu cuối của mình, tôi sẽ thấy "č" (0xE8
). Tương tự, nếu bạn xuất UTF-8 "è" (0xC3 0xA8
), tôi sẽ thấy (ISO-8859-2) "è" (0xC3 0xA8
). Việc chặn các ký tự không chính xác này được gọi là Mojibake.
Thông thường, bạn chỉ cần xáo trộn dữ liệu xung quanh và không quan trọng lắm. Điều này thường xuất hiện khi bạn cần serialize dữ liệu. (Nhiều giao thức internet sử dụng UTF-8 hoặc UTF-16, ví dụ: nếu bạn nhận dữ liệu từ thiết bị đầu cuối ISO-8859-2 hoặc tệp văn bản được mã hóa trong Windows-1252, thì bạn phải chuyển đổi hoặc bạn sẽ gửi Mojibake.)
Đáng buồn thay, đây là trạng thái hỗ trợ Unicode, trong cả C và C++. Bạn phải nhớ: những ngôn ngữ này thực sự là hệ thống bất khả tri, và không ràng buộc với bất kỳ cách cụ thể nào để thực hiện nó. Điều đó bao gồm các bộ ký tự. Tuy nhiên, có rất nhiều thư viện để xử lý Unicode và các bộ ký tự khác.
Cuối cùng, nó không phải là tất cả những gì phức tạp thực sự: Biết những gì mã hóa dữ liệu của bạn, và biết những gì mã hóa đầu ra của bạn nên in Nếu họ không giống nhau, bạn cần phải làm một chuyển đổi. Điều này áp dụng cho dù bạn đang sử dụng std::cout
hoặc std::wcout
. Trong ví dụ của tôi, stdin
hoặc std::cin
và stdout
/std::cout
đôi khi ở dạng UTF-8, đôi khi là ISO-8859-2.
Bạn đã không đề cập đến một nền tảng, nhưng cửa sổ cmd dòng có thể không xử lý unicode rất tốt. Kiểm tra chủ đề này: http://stackoverflow.com/questions/379240/is-there-a-windows-command-shell-that-will-display-unicode-characters – zdav