簡體   English   中英

Delphi 2009 + Unicode + Char-size

[英]Delphi 2009 + Unicode + Char-size

我剛剛獲得Delphi 2009並且之前已經閱讀了一些關於由於切換到Unicode字符串而可能需要的修改的文章。 大多數情況下,提到sizeof(char)不再保證為1。 但是為什么這對於字符串操作會有趣呢?

例如,如果我使用AnsiString:='Test'並對String(現在是unicode)執行相同操作,那么我得到Length()= 4,這對於兩種情況都是正確的。 沒有測試它,我確信所有其他字符串操作函數的行為方式相同,並在內部決定參數是unicode字符串還是其他任何東西。

如果我進行字符串操作,為什么我會對char的實際大小感興趣呢? (當然,如果我使用字符串作為字符串而不存儲任何其他數據)

謝謝你的幫助! 霍爾格

使用Unicode SizeOf(SomeChar)<> Length(SomeChar) 基本上, 字符串的長度小於其字符大小的總和。 只要你不假設SizeOf(Char)= 1 ,或者SizeOf(SomeString [x])= 1 (因為兩者都是FALSE )或嘗試用char s交換字節 s,那么你應該沒有任何麻煩。 你正在做任何創造性地將字節填入Char s或String s的地方,那么你將需要使用AnsiString

(SizeOf(SomeString)仍然是4,無論長度,因為它本質上是一個帶有一些編譯器魔法的指針。)

人們經常在舊的Delphi代碼中隱式地將字符轉換為字節,而沒有真正考慮它。 例如,寫入流時。 將字符串寫入流時,必須指定要寫入的字節數,但人們通常會傳遞字符數。 另見Chris Bensen的這篇文章

人們經常進行隱式轉換和舊代碼的另一種方法是使用“字符串”來存儲二進制數據。 在這種情況下,它們實際上需要字節,但數據類型需要字符。 D2009有更好的類型

我沒有嘗試過Delphi 2009,但是正在使用fpc,它也會慢慢切換到unicode。 我95%肯定以下所有內容也適用於Delphi 2009

在fpc中(當支持unicode時),像'length'這樣的函數會考慮代碼頁。 因此,它將返回字符串的長度,因為“人類”會看到它。 如果有 - 例如 - 兩個中文字符,它們在unicode中占用兩個字節的內存,則長度將返回2,因為字符串中有兩個字符。 但該字符串將占用4個字節的內存。 (+引用計數和前導#0的內存,但除此之外)

你做不了的是這個:

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

因為這個代碼將 - 在兩個中文字符示例中 - 寫錯了兩個字符。 即兩個字節是第一個“真實”字符的一部分。

簡而言之:Length()不再返回為字符串分配的字節數,而是返回字符數。 (在切換到unicode之前,這兩個值彼此相等)

除非您在字節級別進行操作,否則字符的實際大小無關緊要。

(當然,如果我使用字符串作為字符串而不存儲任何其他數據)

這是關鍵點,你不會將字符串用於其他目的,但有些人會這樣做。 他們像數組一樣使用字符串,所以他們(包括我在內)需要檢查所有這些用途以確保沒有任何內容被破壞...

不要忘記有時候這種轉換並不是真正需要的。 比如說,將GUID存儲在記錄中。 guid只能包含十六進制字符加上 - 和括號......使它們占用兩倍的空間可以對現有代碼產生相當大的影響。 當然,簡單的解決方案是將它們更改為AnsiString,並在對它們執行任何字符串操作時處理編譯器警告。

如果您進行Windows API調用,則可能會出現問題。 或者,如果您的遺留代碼使用str [0]的 incdec來改變其長度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM