2008-09-24 46 views
6

我剛剛拿到了Delphi 2009,並且之前閱讀過一些關於因切換到Unicode字符串而可能需要修改的文章。 大多數情況下,提到sizeof(char)不能保證是1。 但是,爲什麼這將有趣的字符串操作?例如,如果我使用AnsiString:='Test'並對String(現在是unicode)執行相同的操作,那麼我將得到Length()= 4,這對兩種情況都是正確的。 未經測試,我確定所有其他字符串操作函數的行爲方式相同,並在內部決定參數是否爲unicode字符串或其他。Delphi 2009 + Unicode + Char大小

如果我做字符串操作,爲什麼字符的實際大小對我來說很有意思? (當然,如果我使用字符串作爲字符串,而不是存儲任何其他數據)

感謝您的幫助! Holger

回答

5

使用Unicode SizeOf(SomeChar)<> Length(SomeChar)。基本上,字符串的長度小於其char s的大小的總和。只要你不承擔中SizeOf(字符)= 1,或一下SizeOf(SomeString [X])= 1(因爲兩者都是現在FALSE)或嘗試交換字節 s的焦炭那麼你不應該有任何麻煩。任何你正在做的事情創造性餡字節之地位爲字符 S或字符串 S,那麼你將需要使用AnsiString類型

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

0

字符的實際大小應該不重要,除非您在字節級別進行操作。

0

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

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

+0

你說得對。我感到困惑,因爲我特別用字符串操作來讀取字符大小將是重要的。當我使用字符串來存儲除字符串以外的其他字符時,當然是由我來正確處理它。 – Holgerwa 2008-09-24 21:13:36

1

我沒有嘗試德爾福2009年,但使用fpc這也是慢慢切換到unicode。我95%確定下面的所有內容也適用於德爾福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之前,這兩個值彼此相等)

4

人們通常會在舊的Delphi代碼中隱式地將字符轉換爲字節,而沒有真正考慮它。例如,寫入流時。當您爲流寫入字符串時,必須指定您寫入的字節數,但人們通常會傳遞字符數。另一個例子見this post from Chris Bensen

人們經常進行這種隱式轉換和老代碼的另一種方式是使用「字符串」來存儲二進制數據。在這種情況下,他們實際上需要字節,但數據類型需要字符。 D2009有a better type for this

0

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

0

它可以是一個問題,如果你讓Windows API調用。或者如果您有舊代碼incdecstr [0]更改其長度。