Hãy xem nếu tôi có thể rõ ràng điều này:
"Multi-byte chuỗi ký tự" là một thuật ngữ mơ hồ để bắt đầu với, nhưng trong thế giới của Microsoft, nó thường meants "không ASCII, và không UTF- 16 ". Vì vậy, bạn có thể sử dụng một số mã hóa ký tự có thể sử dụng 1 byte cho mỗi ký tự hoặc 2 byte hoặc có thể nhiều hơn. Ngay khi bạn thực hiện, số ký tự trong chuỗi! = Số byte trong chuỗi.
Hãy lấy UTF-8 làm ví dụ, mặc dù nó không được sử dụng trên nền tảng MS. Ký tự é được mã hóa là "c3 a9" trong bộ nhớ - do đó, hai byte, nhưng 1 ký tự. Nếu tôi có chuỗi "thé", đó là:
text: t h é \0
mem: 74 68 c3 a9 00
Đây là chuỗi "vô hiệu", ở chỗ nó kết thúc bằng một giá trị rỗng. Nếu chúng ta muốn cho phép chuỗi của chúng tôi để có null trong nó, chúng ta cần phải lưu trữ các kích thước trong một số thời trang khác, chẳng hạn như:
struct my_string
{
size_t length;
char *data;
};
... và một loạt các chức năng để giúp đối phó với điều đó. (Đây là loại bao std::string
công trình, khá gần.)
Đối null-terminated strings, tuy nhiên, strlen()
sẽ tính toán kích thước của chúng theo byte, không ký tự. (Có các chức năng khác để đếm ký tự) strlen
chỉ đếm số byte trước khi nó thấy 0 byte - không có gì lạ mắt.
Hiện tại, chuỗi "rộng" hoặc "unicode" trong thế giới của MS đề cập đến chuỗi UTF-16. Họ có vấn đề tương tự trong đó số byte! = Số lượng ký tự. (Ngoài ra: số byte/2 = số ký tự!) Chúng ta hãy nhìn vào một lần nữa:
text: t h é \0
shorts: 0x0074 0x0068 0x00e9 0x0000
mem: 74 00 68 00 e9 00 00 00
Đó là "the" trong UTF-16, được lưu trữ trong little endian (đó là những gì máy tính để bàn tiêu biểu của bạn là). Chú ý tất cả các byte 00 - các strlen chuyến đi này. Do đó, chúng tôi gọi wcslen
, xem nó là 2 byte short
s, không phải byte đơn.
Cuối cùng, bạn có TCHAR
s, là một trong hai trường hợp trên, tùy thuộc vào nếu UNICODE
được xác định. _tcslen
sẽ là chức năng thích hợp (hoặc strlen
hoặc wcslen
) và TCHAR
sẽ là char
hoặc wchar_t
. TCHAR
được tạo để dễ dàng di chuyển sang UTF-16 trong thế giới Windows.
Mã của bạn là chính xác, để tính kích thước theo byte, của chuỗi. Câu lệnh "làm việc cho ... char và wchar_t ... nhưng không phải cho chuỗi ký tự nhiều byte". – Thanatos
Vì vậy, chuỗi ký tự nhiều byte không chứa byte rỗng? – flacs
@Tilka: Chúng có thể, nhưng bạn cần phải biết độ dài theo một số cách khác, chẳng hạn như lưu trữ nó trong một số nguyên đi kèm với chuỗi. Các chuỗi được kết thúc bằng Null, là những gì thường gặp (và những gì _tcslen, strlen, vv yêu cầu), không chứa các byte null, ngoại trừ terminator null, tất nhiên. – Thanatos