2012-03-18 9 views
10

nhà phát triển phần mềm được ưa thích và các công ty (Joel Spolsky, Fog Creek software) có xu hướng sử dụng wchar_t cho Unicode nhân vật lưu trữ khi viết C hoặc C++. Khi nào và như thế nào nên sử dụng charwchar_t đối với các phương pháp mã hóa tốt?sử dụng đúng dung lượng lưu trữ chuỗi trong C và C++

Tôi đặc biệt quan tâm đến việc tuân thủ POSIX khi viết phần mềm thúc đẩy Unicode.

Khi sử dụng wchar_t, bạn có thể tra cứu các nhân vật trong một loạt các ký tự rộng trên một cơ sở cho mỗi nhân vật hoặc mỗi mảng phần tử:

/* C code fragment */ 
const wchar_t *overlord = L"ov€rlord"; 
if (overlord[2] == L'€') 
    wprintf(L"Character comparison on a per-character basis.\n"); 

Làm thế nào bạn có thể so sánh byte unicode (hoặc ký tự) khi sử dụng char?

Cho đến nay tôi thích cách so sánh chuỗi và các nhân vật kiểu char trong C thường trông như thế này:

/* C code fragment */ 
const char *mail[] = { "ov€[email protected]", "ov€[email protected]" }; 
if (mail[0][2] == mail[1][2] && mail[0][3] == mail[1][3] && mail[0][3] == mail[1][3]) 
    printf("%s\n%zu", *mail, strlen(*mail)); 

Phương pháp này quét tương đương byte của một ký tự unicode. Biểu tượng Unicode Euro chiếm 3 byte. Vì vậy, một trong những nhu cầu để so sánh ba byte mảng byte để biết nếu các ký tự Unicode phù hợp. Thông thường, bạn cần phải biết kích thước của ký tự hoặc chuỗi bạn muốn so sánh và các bit mà nó tạo ra để giải pháp hoạt động. Điều này không giống như một cách tốt để xử lý Unicode cả. Có cách nào tốt hơn để so sánh các chuỗi và các yếu tố nhân vật thuộc loại char?

Ngoài ra, khi sử dụng wchar_t, cách bạn có thể quét nội dung tệp vào một mảng? Hàm fread dường như không tạo ra kết quả hợp lệ.

+9

Unicode trong C++: không sử dụng 'wchar_t', sử dụng thư viện Unicode phù hợp. –

+3

'có xu hướng sử dụng wchar_t cho mã hóa ký tự Unicode'. Không; họ sử dụng nó cho ký tự Unicode _storage_, và có một sự khác biệt lớn. –

+0

có thể trùng lặp của [std :: wstring VS std :: string] (http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring) –

Trả lời

10

Nếu bạn biết rằng bạn đang xử lý unicode, không char cũng không wchar_t phù hợp vì kích thước của chúng là trình biên dịch/nền tảng được xác định. Ví dụ: wchar_t là 2 byte trên Windows (MSVC), nhưng 4 byte trên Linux (GCC). Các tiêu chuẩn C11 và C++ 11 đã nghiêm ngặt hơn một chút và xác định hai loại ký tự mới (char16_tchar32_t) với các tiền tố chữ có liên quan để tạo chuỗi UTF- {8, 16, 32}.

Nếu bạn cần lưu trữ và thao tác các ký tự unicode, bạn nên sử dụng thư viện được thiết kế cho công việc, vì không phải chuẩn C11 cũng như ngôn ngữ trước C++ 11 đã được viết với unicode. Có một few to choose from, nhưng ICU là khá phổ biến (và hỗ trợ C, C++ và Java).

+3

Ngay cả C++ 11 khá nhẹ trên các công cụ unicode. Ngoài việc bắt buộc một vài loại và chuyển đổi chuẩn giữa utf8/16/32, bạn sẽ không tìm thấy bất kỳ thứ gì như đối chiếu, so sánh, chuẩn hóa, v.v. –

+0

Giống như bổ sung, tôi nghĩ C11 ở đây sẽ cố đồng bộ với C++ 1 và giới thiệu cùng loại 'char ?? _ t' mới. –

+0

Có, C11 được đồng bộ hóa với C++ 11 cho các loại/literals này. –

0

tôi đặc biệt quan tâm đến việc POSIX tuân thủ khi viết phần mềm đó thúc đẩy Unicode.

Trong trường hợp này, bạn có thể muốn sử dụng UTF-8 (với char) làm loại chuỗi Unicode ưa thích của mình.POSIX không có nhiều chức năng để làm việc với wchar_t — chủ yếu là điều Windows.

Phương pháp này quét byte tương đương với ký tự unicode. Biểu tượng Euro Euro € chiếm 3 byte. Vì vậy, cần phải so sánh ba byte mảng byte để biết các ký tự Unicode có khớp không. Thường thì bạn cần phải biết kích thước của ký tự hoặc chuỗi bạn muốn so sánh với số bit hoặc bit mà nó tạo ra để giải pháp hoạt động.

Không, bạn không. Bạn chỉ cần so sánh các byte. Iff các byte phù hợp, các chuỗi phù hợp. strcmp hoạt động tốt với UTF-8 như với bất kỳ mã hóa nào khác.

Trừ khi bạn muốn một thứ gì đó giống như so sánh không phân biệt chữ hoa hoặc chữ thường, trong trường hợp đó bạn sẽ cần một thư viện Unicode thích hợp.

0

Bạn không bao giờ nên so sánh các byte hoặc thậm chí là các điểm mã để quyết định xem các chuỗi có bằng nhau hay không. Đó là bởi vì rất nhiều chuỗi có thể giống hệt nhau từ quan điểm của người dùng mà không giống với quan điểm điểm mã.