2013-09-07 65 views
6

Nếu tôi hiểu rõ, có thể sử dụng cả chuỗi và chuỗi để lưu trữ văn bản UTF-8.std :: chuỗi và UTF-8 mã hóa unicode

  • Với char, các ký tự ASCII mất một byte duy nhất, một số ký tự Trung Quốc mất 3 hoặc 4, vv Mà có nghĩa là str[3] không nhất thiết chỉ với nhân vật thứ 4.

  • Với wchar_t điều tương tự, nhưng số lượng tối thiểu của các byte được sử dụng cho mỗi nhân vật luôn luôn là 2 (thay vì 1 cho char), và một nhân vật rộng 3 hoặc 4 byte sẽ mất 2 wchar_t.

Phải không?

Vì vậy, điều gì xảy ra nếu tôi muốn sử dụng string::find_first_of() hoặc string::compare(), v.v ... với chuỗi được mã hóa kỳ lạ như vậy? Nó có hoạt động không? Lớp chuỗi có xử lý thực tế là các ký tự có kích thước biến không? Hoặc tôi chỉ nên sử dụng chúng như là mảng byte ít tính năng giả, trong trường hợp này tôi muốn sử dụng bộ đệm wchar_t[].

Nếu std::string không xử lý câu hỏi thứ hai: có thư viện cung cấp các lớp chuỗi có thể xử lý mã hóa UTF-8 đó để str[3] thực sự trỏ đến ký tự thứ 3 (sẽ là mảng byte từ 1 đến 4)?

+0

Lưu ý rằng ngay cả khi 'str [3]' là điểm mã thứ tư, thì đó không nhất thiết là ký tự thứ tư của người dùng. – delnan

+1

@delnan _Ok xin lỗi (Tôi vừa chọn một bài viết ví dụ về wchar_t, Windows và UTF-16). Vì đã quá muộn để chỉnh sửa tôi đã xóa nhận xét và đây là phần không có liên kết "gây tranh cãi": _ Tôi nghĩ rằng kích thước của 'wchar_t' được xác định thực hiện, vì vậy _not_ luôn luôn là 2 byte. Hơn nữa (IIRC) Windows sử dụng nó để lưu trữ một cái gì đó như UTF-16, không phải UTF-8. Xem http://en.wikipedia.org/wiki/Wide_character –

Trả lời

5

Bạn đang nói về Unicode. Unicode sử dụng 32 bit để biểu diễn một ký tự. Tuy nhiên vì đó là lãng phí bộ nhớ có mã hóa nhỏ gọn hơn. UTF-8 là một mã hóa như vậy. Nó giả định rằng bạn đang sử dụng các đơn vị byte và nó ánh xạ các ký tự Unicode tới 1, 2, 3 hoặc 4 byte. UTF-16 là một từ khác sử dụng các từ như đơn vị và ánh xạ các ký tự Unicode tới 1 hoặc 2 từ (2 hoặc 4 byte). Bạn có thể sử dụng cả hai mã hóa với cả chuỗi và wchar_t. UTF-8 có xu hướng nhỏ gọn hơn cho văn bản/số tiếng Anh.

Một số thứ sẽ hoạt động bất kể mã hóa và loại được sử dụng (so sánh). Tuy nhiên tất cả các chức năng cần hiểu một ký tự sẽ bị hỏng. I. Nhân vật thứ 5 không phải lúc nào cũng là mục thứ 5 trong mảng cơ bản. Nó có thể trông giống như nó làm việc với một số ví dụ nhưng cuối cùng nó sẽ phá vỡ. chuỗi :: so sánh sẽ hoạt động nhưng không mong đợi để có được thứ tự chữ cái. Đó là ngôn ngữ phụ thuộc. chuỗi :: find_first_of sẽ hoạt động đối với một số nhưng không phải tất cả. Chuỗi dài sẽ có khả năng hoạt động chỉ vì chúng dài trong khi các chuỗi ngắn hơn có thể bị nhầm lẫn bởi việc căn chỉnh ký tự và tạo ra rất khó tìm lỗi.

Điều tốt nhất là tìm thư viện xử lý nó cho bạn và bỏ qua loại bên dưới (trừ khi bạn có lý do chính đáng để chọn một hoặc loại kia).

+0

Cảm ơn câu trả lời của bạn. – Virus721

+5

* Unicode sử dụng 32 bit để đại diện cho một ký tự. * => Thực sự phụ thuộc vào những gì bạn gọi là một ký tự. Unicode định nghĩa các điểm mã (số nguyên) và đồ thị (chuỗi các số nguyên, thường là kích thước 1) và mọi người có xu hướng liên kết "ký tự" với "grapheme" bởi vì nó là thực thể trực quan xuất hiện trên màn hình. –

+0

_Unicode sử dụng 32 bit để đại diện cho một ký tự._ Điều này là không chính xác! Unicode không ** không ** sử dụng bất kỳ số bit nào để biểu diễn một ký tự. Unicode hoàn toàn trừu tượng. Nó gán một số cho mỗi ký tự. Nó không chỉ định số lượng bit đại diện cho ký tự đó. Các mã hóa không phải là "nhỏ gọn hơn" cách để đại diện cho các nhân vật, họ ** là ** cách để đại diện cho các ký tự. Xem https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ – Len

-1

Bạn là chính xác đối với những:
... Có nghĩa là str [3] không nhất thiết chỉ với nhân vật thứ 4 ... chỉ sử dụng chúng như tính năng ít giả byte mảng ...

chuỗi C++ chỉ có thể xử lý các ký tự ascii. Điều này khác với Chuỗi Java, có thể xử lý các ký tự Unicode. Bạn có thể lưu trữ kết quả mã hóa (byte) của ký tự Trung Quốc thành chuỗi (char trong C/C++ chỉ là byte), nhưng điều này là vô nghĩa khi chuỗi chỉ xử lý các byte như ký tự ascii, vì vậy bạn không thể sử dụng hàm chuỗi để xử lý nó.
chuỗi có thể là thứ bạn cần.

Có điều cần làm rõ. UTF-8 chỉ là một phương pháp mã hóa cho các ký tự Unicode (chuyển đổi các ký tự từ/sang định dạng byte).

+0

Cảm ơn câu trả lời của bạn. Những gì tôi muốn biết là những gì các phương pháp của lớp chuỗi vẫn sẽ làm việc khi sử dụng một văn bản được mã hóa UTF-8. – Virus721

+0

-1 'std :: string' store' char's. Nhưng điều đó không có nghĩa là nó bị giới hạn trong ASCII, nó chỉ có nghĩa là nó không biết gì về mã hóa, vì vậy bạn có thể sử dụng nó cho bất kỳ mã hóa nào (và do đó làm hỏng mọi thứ nếu bạn không cẩn thận). Và chuỗi của Java là một mảng UTF-16, do đó, 'str [3]' không nhất thiết phải là điểm mã thứ tư. – delnan

+0

@delnan Hãy bỏ phiếu xuống sau khi hoàn thành câu trả lời của tôi. Tôi đã nói điều này "Bạn có thể lưu trữ kết quả mã hóa (byte) của ký tự Trung Quốc thành chuỗi (char trong C/C++ chỉ là byte), nhưng điều này là vô nghĩa khi chuỗi chỉ xử lý các byte như ký tự ascii, vì vậy bạn không thể sử dụng hàm chuỗi để xử lý nó. "Tôi đã nói" chuỗi C++ chỉ có thể xử lý các ký tự ascii. " không phải "chuỗi C++ chỉ có thể lưu trữ các ký tự ascii." HANDLE khác với STORE. chức năng chuỗi sẽ vô nghĩa khi bạn chỉ sử dụng nó để lưu trữ byte, đó là lý do tại sao tôi sử dụng HANDLE. Cảm ơn. – JackyZhu

2

Bạn không thể xử lý Unicode với chuỗi std :: hoặc bất kỳ công cụ nào khác từ Thư viện chuẩn. Sử dụng thư viện bên ngoài như: http://utfcpp.sourceforge.net/

+0

Cảm ơn tôi sẽ có một cái nhìn. – Virus721