2010-07-28 38 views
8

Làm cách nào để nhận kích thước byte của chuỗi ký tự nhiều byte trong Visual C? Có chức năng nào hay tôi có phải tự tính mình không?Cách nhận kích thước byte của chuỗi nhiều byte

Hoặc, tổng quát hơn, làm cách nào để nhận được kích thước byte đúng của chuỗi TCHAR?

Giải pháp:

_tcslen(_T("TCHAR string")) * sizeof(TCHAR) 

EDIT:
tôi đã nói về chỉ null-terminated strings.

+3

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

+0

Vì vậy, chuỗi ký tự nhiều byte không chứa byte rỗng? – flacs

+0

@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

Trả lời

3

According to MSDN, _tcslen tương ứng với strlen khi _MBCS được xác định. strlen sẽ trả về số lượng byte trong chuỗi. Nếu bạn sử dụng _tcsclen tương ứng với _mbslen sẽ trả về số lượng đa byte ký tự.

Ngoài ra, các chuỗi nhiều byte không (AFAIK) chứa các giá trị rỗng được nhúng, không.

Tôi sẽ đặt câu hỏi về việc sử dụng mã hóa nhiều byte ở vị trí đầu tiên, mặc dù ... trừ khi bạn đang hỗ trợ ứng dụng cũ, không có lý do gì để chọn đa byte trên Unicode.

+1

Chuỗi UTF-8 không chứa các giá trị rỗng được nhúng (cụ thể: nơi duy nhất một byte 0 xảy ra là đại diện cho mã 0, vì vậy nếu đó là terminator của bạn thì bạn có thể tìm kiếm nó theo byte). Tôi không chắc liệu UTF-16 có được coi là "mã hóa đa byte" trong ngữ cảnh này hay không, nhưng nó chắc chắn có thể chứa 0 * byte *, không chỉ 0 byte đôi. Tôi nghĩ rằng SHIFT-JIS không sử dụng 0 byte trừ khi mã hóa 0. Rất nhiều mã hóa trên thế giới, nhưng tôi không chắc chắn những gì có thể trong miền địa phương của Windows ... –

+1

Đó là một chút lộn xộn: UTF-8 chuỗi có thể chứa null , * nếu * bạn đang lưu trữ kích thước trong một cái gì đó khác với một terminator null. Các chuỗi đã kết thúc không thể chứa null, vì chúng không được kết thúc. Một chuỗi vô hiệu UTF-8 không thể chứa null cho cùng một lý do. Điều đó nói rằng, tôi không thể nghĩ ra bất kỳ mục đích hữu ích để đặt một null trong một chuỗi UTF-8 khác hơn là chấm dứt nó. – Thanatos

9

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.

+0

"(Ngoài ra: số byte/2! = Số ký tự)" Làm thế nào? – flacs

+0

@Tilka: Đó là cách UTF-16 mã hóa các ký tự. UTF-16 có thể mã hóa hơn 65,536 ký tự khác nhau, vì vậy cần phải rõ ràng là 2 byte không đủ. UTF-16 mã hóa nhiều ký tự chỉ 2 byte, nhưng phải sử dụng 4 cho một số, dưới dạng "cặp thay thế" (Xem bài viết trên UTF-16 của Wikipedia.) – Thanatos

+0

Ah vâng, tôi đã nhầm lẫn với UCS-2. Nice giải thích btw, nhưng câu trả lời khác là thẳng vào vấn đề. – flacs

Các vấn đề liên quan