2008-09-24 35 views
6

Tôi vừa có Delphi 2009 và trước đây đã đọc một số bài viết về sửa đổi có thể cần thiết vì chuyển sang chuỗi Unicode. Chủ yếu là, sizeof (char) không được bảo đảm là 1 nữa. Nhưng tại sao điều này lại thú vị về thao tác chuỗi?Delphi 2009 + Unicode + Char-size

Ví dụ: nếu tôi sử dụng AnsiString: = 'Test' và thực hiện tương tự với chuỗi (bây giờ là unicode), thì tôi nhận Độ dài() = 4, điều này đúng cho cả hai trường hợp. Nếu không có thử nghiệm nó, tôi chắc chắn rằng tất cả các chức năng thao tác chuỗi khác hành xử theo cùng một cách và quyết định nội bộ nếu đối số là một chuỗi unicode hoặc bất cứ điều gì khác.

Tại sao kích thước thực sự của một char được tôi quan tâm nếu tôi thực hiện thao tác chuỗi? (Tất nhiên nếu tôi sử dụng chuỗi như chuỗi và không lưu trữ bất kỳ dữ liệu nào khác)

Cảm ơn bạn đã trợ giúp! Holger

Trả lời

5

Với Unicode SizeOf (SomeChar) <> Chiều dài (SomeChar). Về cơ bản, độ dài của một chuỗi nhỏ hơn tổng kích thước của char s của nó. Chừng nào bạn đừng cho rằng sizeof (char) = 1, hoặc sizeof (SomeString [x]) = 1 (vì cả hai đều FALSE bây giờ) hoặc cố gắng trao đổi byte s với char s, sau đó bạn không nên có bất kỳ rắc rối. Bất cứ nơi bạn đang làm một cái gì đó sáng tạo stuffing Byte s vào Char s hoặc Chuỗi s, sau đó bạn sẽ cần phải sử dụng AnsiString.

(sizeof (SomeString) vẫn là 4 không có vấn đề dài vì nó thực chất là một con trỏ với một số trình biên dịch ma thuật.)

0

Kích thước thực tế của một ký tự không thành vấn đề, trừ khi bạn đang thực hiện thao tác ở cấp byte.

0

(Tất nhiên nếu tôi sử dụng chuỗi như dây đàn và không lưu trữ bất kỳ dữ liệu khác)

Đó là điểm mấu chốt, bạn không sử dụng dây cho các mục đích khác, nhưng một số người làm. Họ sử dụng chuỗi giống như mảng, vì vậy họ (và đó là bao gồm cả tôi) sẽ cần phải kiểm tra tất cả các sử dụng như vậy để đảm bảo không có gì bị hỏng ...

+0

Bạn nói đúng. Tôi đã bối rối bởi vì tôi đọc cụ thể với các thao tác chuỗi kích thước char sẽ là quan trọng. Khi tôi sử dụng các chuỗi để lưu trữ bất kỳ thứ gì khác ngoài các chuỗi, tất nhiên điều đó tùy thuộc vào tôi để xử lý nó một cách chính xác. – Holgerwa

1

Tôi đã không thử Delphi 2009, nhưng đang sử dụng fpc cũng là chuyển sang chế độ unicode chậm. Tôi chắc chắn 95% rằng mọi thứ bên dưới cũng được lưu giữ cho Delphi 2009

Trong fpc (khi hỗ trợ unicode), các chức năng như 'length' sẽ xem xét mã. Vì vậy, nó sẽ trả về độ dài của chuỗi như một 'con người' sẽ thấy nó. Nếu có - ví dụ - hai ký tự Trung Quốc, cả hai mất hai byte bộ nhớ trong unicode, chiều dài sẽ trở lại 2, vì có hai ký tự trong chuỗi. Nhưng chuỗi sẽ mất 4 byte bộ nhớ. (+ Bộ nhớ cho các tính tham khảo và hàng đầu # 0, nhưng điều đó sang một bên)

gì bạn không thể làm được nữa đây là:

var p : pchar; 
begin 
    p := s[1]; 
    for i := 0 to length(string)-1 do 
    begin 
    write(p); 
    inc(p); 
    end;  
end; 

Bởi vì mã này sẽ - trong ví dụ hai Trung Quốc ký tự - viết sai hai ký tự. Cụ thể là hai byte là một phần của ký tự 'thực' đầu tiên.

Tóm lại: Độ dài() không trả về số byte được phân bổ cho chuỗi nữa, nhưng số lượng ký tự. (Trước khi chuyển sang unicode, hai giá trị đó bằng nhau)

4

Mọi người thường chuyển đổi hoàn toàn từ ký tự thành byte trong mã Delphi cũ mà không thực sự nghĩ về nó. Ví dụ: khi ghi vào luồng. Khi bạn viết một chuỗi vào luồng, bạn phải chỉ định số byte bạn viết, nhưng mọi người thường chuyển số ký tự thay vào đó. Xem this post from Chris Bensen để biết ví dụ khác.

Một cách khác mà mọi người thường thực hiện chuyển đổi tiềm ẩn này và mã cũ hơn là sử dụng "chuỗi" để lưu trữ dữ liệu nhị phân. Trong trường hợp này, họ thực sự muốn byte, nhưng kiểu dữ liệu mong đợi các ký tự. D2009 có a better type for this.

0

Đừng quên rằng có những lúc chuyển đổi này không thực sự mong muốn. Nói cho việc lưu trữ một GUID trong một bản ghi chẳng hạn. Các guid chỉ có thể chứa các ký tự thập lục phân cộng với dấu ngoặc và ... làm cho chúng chiếm hai lần không gian có thể tạo ra tác động khá lớn lên mã hiện có. Chắc chắn giải pháp đơn giản là thay đổi chúng thành AnsiString và xử lý cảnh báo trình biên dịch nếu bạn thực hiện bất kỳ thao tác chuỗi nào trên chúng.

0

Nó có thể là một vấn đề nếu bạn thực hiện cuộc gọi Windows API. Hoặc nếu bạn có mã kế thừa có inc hoặc tháng 12 của str [0] để thay đổi độ dài của nó.

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