Giả sử môi trường Linux của bạn sử dụng mã UTF-8 sau đó đoạn mã sau sẽ chuẩn bị chương trình của bạn để điều trị Unicode dễ dàng trong C++:
int main(int argc, char * argv[]) {
std::setlocale(LC_CTYPE, "");
// ...
}
Tiếp theo, gõ wchar_t là 32-bit trong Linux, có nghĩa là nó có thể giữ các điểm mã Unicode riêng lẻ và bạn có thể sử dụng một cách an toàn loại xâu chuỗi để xử lý chuỗi cổ điển trong C++ (ký tự theo ký tự). Với cuộc gọi setlocale ở trên, chèn vào wcout sẽ tự động dịch đầu ra của bạn thành UTF-8 và giải nén từ wcin sẽ tự động dịch đầu vào UTF-8 thành UTF-32 (1 ký tự = 1 điểm mã). Vấn đề duy nhất còn lại là các chuỗi argv [i] vẫn được mã hoá UTF-8.
Bạn có thể sử dụng hàm sau để giải mã UTF-8 thành UTF-32.Nếu chuỗi đầu vào bị hỏng, nó sẽ trả về các ký tự được chuyển đổi đúng cho đến khi các quy tắc UTF-8 bị hỏng. Bạn có thể cải thiện nó nếu bạn cần báo cáo lỗi hơn. Nhưng đối với dữ liệu argv một cách an toàn có thể giả định rằng nó là đúng UTF-8:
#define ARR_LEN(x) (sizeof(x)/sizeof(x[0]))
wstring Convert(const char * s) {
typedef unsigned char byte;
struct Level {
byte Head, Data, Null;
Level(byte h, byte d) {
Head = h; // the head shifted to the right
Data = d; // number of data bits
Null = h << d; // encoded byte with zero data bits
}
bool encoded(byte b) { return b>>Data == Head; }
}; // struct Level
Level lev[] = {
Level(2, 6),
Level(6, 5),
Level(14, 4),
Level(30, 3),
Level(62, 2),
Level(126, 1)
};
wchar_t wc = 0;
const char * p = s;
wstring result;
while (*p != 0) {
byte b = *p++;
if (b>>7 == 0) { // deal with ASCII
wc = b;
result.push_back(wc);
continue;
} // ASCII
bool found = false;
for (int i = 1; i < ARR_LEN(lev); ++i) {
if (lev[i].encoded(b)) {
wc = b^lev[i].Null; // remove the head
wc <<= lev[0].Data * i;
for (int j = i; j > 0; --j) { // trailing bytes
if (*p == 0) return result; // unexpected
b = *p++;
if (!lev[0].encoded(b)) // encoding corrupted
return result;
wchar_t tmp = b^lev[0].Null;
wc |= tmp << lev[0].Data*(j-1);
} // trailing bytes
result.push_back(wc);
found = true;
break;
} // lev[i]
} // for lev
if (!found) return result; // encoding incorrect
} // while
return result;
} // wstring Convert
Nguồn
2012-07-07 11:50:59