2008-09-24 71 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]更改其长度。