2008-09-19 35 views
12

Tôi vẫn đang cố gắng quyết định xem dự án (nhà) của tôi có nên sử dụng các chuỗi UTF-8 (được triển khai dưới dạng chuỗi std :: với các hàm UTF-8 cụ thể khi cần thiết) hay chuỗi 16 bit (được triển khai dưới dạng std: : wstring). Dự án là một ngôn ngữ lập trình và môi trường (như VB, nó là sự kết hợp của cả hai).Chuỗi C++: mã hóa UTF-8 hoặc 16 bit?

Có một vài điều ước/hạn chế:

  • Nó sẽ là tuyệt vời nếu nó có thể chạy trên các phần cứng hạn chế, chẳng hạn như máy tính với bộ nhớ hạn chế.
  • Tôi muốn mã chạy trên Windows, Mac và (nếu tài nguyên cho phép) Linux.
  • Tôi sẽ sử dụng wxWidgets làm lớp GUI, nhưng tôi muốn mã tương tác với bộ công cụ đó được giới hạn ở một góc của codebase (tôi sẽ có các tệp thi hành không phải GUI).
  • Tôi muốn tránh làm việc với hai loại chuỗi khác nhau khi làm việc với văn bản có thể nhìn thấy của người dùng và với dữ liệu của ứng dụng.

Hiện tại, tôi đang làm việc với std :: string, với mục đích sử dụng các chức năng thao tác UTF-8 chỉ khi cần thiết. Nó đòi hỏi bộ nhớ ít hơn, và dường như là hướng nhiều ứng dụng đang đi anyway.

Nếu bạn đề xuất mã hóa 16 bit, cái nào: UTF-16? UCS-2? Một cái khác?

+1

Micro ATX không có nghĩa là bộ nhớ bị giới hạn. PC của tôi ở nhà là trên một (Micro-ATX) ASUS M2A-VM, và nó chạy Crysis tốt. – notJim

+0

Tôi đã chỉnh sửa câu hỏi để xóa lỗi. –

Trả lời

2

Tôi muốn giới thiệu UTF-16 cho bất kỳ loại thao tác dữ liệu và giao diện người dùng nào. Mac OS X và Win32 API sử dụng UTF-16, tương tự cho wxWidgets, Qt, ICU, Xerces và các thiết bị khác. UTF-8 có thể tốt hơn cho việc trao đổi và lưu trữ dữ liệu. Xem http://unicode.org/notes/tn12/.

Nhưng bất cứ điều gì bạn chọn, tôi chắc chắn sẽ khuyên bạn nên chống lại std :: string with UTF-8 "only when needed".

Thực hiện theo mọi cách với UTF-16 hoặc UTF-8, nhưng không trộn lẫn và khớp, điều đó gây khó khăn.

+1

Lập trình viên của nhóm Mac của tôi nói wchar_t là 32 bit. Và chắc chắn có rất nhiều mã trong codebase của chúng tôi mà sẽ phá vỡ khác. – MSalters

+0

Chỉ cần làm rõ: với "utf-8 chỉ khi cần thiết", tôi thực sự có nghĩa là tôi sẽ sử dụng một số chức năng thao tác utf-8 chỉ khi tôi thực sự cần xử lý các ký tự - nhưng tất cả các chuỗi sẽ * luôn * là utf-8 . –

+0

Đã chấp nhận: Tôi muốn tách biệt rõ ràng giữa các miền GUI và dữ liệu. Sau này sẽ là tất cả về trao đổi và lưu trữ, vì vậy tôi không nhớ lớp GUI chuyển đổi thành utf-16 wxStrings từ utf-8 được mã hóa std :: string objects. –

1

Từ nội dung tôi đã đọc, tốt hơn nên sử dụng mã hóa 16 bit bên trong trừ khi bạn thiếu bộ nhớ. Nó phù hợp với hầu hết các ngôn ngữ sống trong một ký tự

Tôi cũng xem ICU. Nếu bạn không sử dụng một số tính năng của chuỗi STL, việc sử dụng các kiểu chuỗi ICU có thể tốt hơn cho bạn.

+0

Trên thực tế, UTF-16 sẽ phù hợp với hầu hết các ký tự ngôn ngữ sống trong hai byte; hãy xem [biểu đồ điểm mã] [http://unicode.org/charts/PDF/] cho các điểm mã trên U + 10000; chúng là tất cả các biểu tượng Hy Lạp hoặc La Mã cổ đại. –

+0

Ben Straub: Cảm ơn. Cố định trong bài viết của tôi – Branan

6

Tôi chưa bao giờ tìm thấy bất kỳ lý do nào để sử dụng bất kỳ điều gì khác ngoài UTF-8 thành thật.

2

MicroATX là một định dạng bo mạch chủ PC chuẩn, có khả năng chứa 4-8 GB bộ nhớ RAM. Nếu bạn đang nói picoATX có thể bạn bị giới hạn ở mức 1-2 GB RAM. Thậm chí sau đó đó là rất nhiều cho một môi trường phát triển. Tôi vẫn gắn bó với UTF-8 vì những lý do nêu trên, nhưng bộ nhớ không phải là mối quan tâm của bạn.

+0

@Peter Mortensen, Bản chỉnh sửa này là gì? –

+0

@Patrick Niedzielski: http://stackoverflow.com/posts/103551/revisions –

+0

@ Peter Mortensen: Ah, cảm ơn. Không biết về tính năng đó. –

26

UTF-16 vẫn là mã hóa ký tự có độ dài thay đổi (có hơn 2^16 điểm mã hóa unicode), vì vậy bạn không thể thực hiện các hoạt động lập chỉ mục chuỗi (1). Nếu bạn đang làm rất nhiều thứ như vậy, bạn sẽ không tiết kiệm được gì với tốc độ UTF-8. Mặt khác, nếu văn bản của bạn bao gồm rất nhiều codepoints trong phạm vi 256-65535, UTF-16 có thể là một sự cải thiện đáng kể về kích thước. UCS-2 là biến thể trên UTF-16 rằng chiều dài cố định, với chi phí cấm bất kỳ điểm mã nào lớn hơn 2^16.

Nếu không biết thêm về yêu cầu của bạn, tôi sẽ đích thân đi UTF-8. Đó là cách dễ nhất để giải quyết vì tất cả những lý do mà những người khác đã liệt kê.

+1

+1 về sự khác biệt giữa UCS2 và UTF-16 – Eonil

0

Bạn đã cân nhắc sử dụng wxStrings chưa? Nếu tôi nhớ chính xác, họ có thể làm utf-8 < -> chuyển đổi Unicode và nó sẽ làm cho nó dễ dàng hơn một chút khi bạn phải vượt qua chuỗi đến và đi từ giao diện người dùng.

5

Nếu bạn quyết định đi với mã UTF-8, hãy kiểm tra thư viện này: http://utfcpp.sourceforge.net/

Nó có thể làm cho cuộc sống của bạn dễ dàng hơn nhiều.

4

Tôi đã thực sự viết một ứng dụng được sử dụng rộng rãi (5 triệu người dùng) nên mỗi kilobyte được sử dụng tăng lên theo nghĩa đen. Mặc dù vậy, tôi chỉ bị mắc kẹt với wxString. Tôi đã cấu hình nó được bắt nguồn từ std :: wstring, vì vậy tôi có thể chuyển chúng đến các hàm mong đợi một wstring const &. Vui lòng lưu ý rằng std :: wstring là Unicode gốc trên máy Mac (không cần UTF-16 cho các ký tự trên U + 10000), và do đó nó sử dụng 4 byte/wchar_t. Ưu điểm lớn của việc này là i ++ giúp bạn trở thành nhân vật tiếp theo, luôn luôn. Trên Win32 đó là đúng chỉ trong 99,9% các trường hợp. Là một lập trình viên, bạn sẽ hiểu được 99,9% là bao nhiêu.

Nhưng nếu bạn không bị thuyết phục, hãy viết hàm này thành chữ hoa std :: string [UTF-8] và std :: wstring. Những chức năng 2 sẽ cho bạn biết cách nào là điên rồ.

Định dạng trên đĩa của bạn là một vấn đề khác. Đối với tính di động, đó phải là UTF-8. Không có mối quan tâm về endianness trong UTF-8, cũng không phải là một cuộc thảo luận về chiều rộng (2/4). Điều này có thể là lý do tại sao nhiều chương trình xuất hiện để sử dụng UTF-8.

Trên ghi chú hơi không liên quan, vui lòng đọc lên các so sánh chuỗi Unicode và chuẩn hóa. Hoặc bạn sẽ kết thúc với cùng một lỗi như .NET, nơi bạn có thể có hai biến föö và föö khác nhau chỉ trong (vô hình) chuẩn hóa.

+2

Lưu ý rằng việc sử dụng UTF32 trên mac sử dụng nhiều bộ nhớ. Trường hợp 0,1% bạn đề cập có nghĩa là bất kỳ wstring nào trên Mac sẽ lớn hơn hai lần so với cùng một chuỗi trong UTF16 trên Windows (tôi thậm chí sẽ không đề cập đến char của Linux). Điều này * là * một trong những lý do Linux sử dụng UTF-8 char, và tại sao Windows sử dụng UTF-16 wchar_t. – paercebal