我刚刚获得Delphi 2009并且之前已经阅读了一些关于由于切换到Unicode字符串而可能需要的修改的文章。 大多数情况下,提到sizeof(char)不再保证为1。 但是为什么这对于字符串操作会很有意思呢?

例如,如果我使用AnsiString:='Test'并对String(现在是unicode)执行相同操作,那么我得到Length()= 4,这对于两种情况都是正确的。 没有测试它,我确信所有其他字符串操作函数的行为方式相同,并在内部决定参数是unicode字符串还是其他任何东西。

如果我进行字符串操作,为什么我会对char的实际大小感兴趣? (当然,如果我使用字符串作为字符串而不存储任何其他数据)

感谢您的帮助!   霍尔格

有帮助吗?

解决方案

使用Unicode SizeOf(SomeChar)<!> lt; <!> gt;长度(SomeChar)。基本上字符串的长度小于其字符串的大小总和。只要您不假设 SizeOf(Char)= 1 SizeOf(SomeString [x])= 1 (因为两者都 FALSE 现在)或尝试将字节 char 交换,那么你应该没有任何问题。你正在做字符 s或字符串的创意填充字节的任何地方,那么你需要使用 AnsiString

(SizeOf(SomeString)仍然是4,无论长度如何,因为它本质上是一个带有一些编译器魔法的指针。)

其他提示

人们经常在旧的Delphi代码中隐式地将字符转换为字节,而没有真正考虑它。例如,写入流时。将字符串写入流时,必须指定要写入的字节数,但人们通常会传递字符数。请参阅Chris Bensen的这篇文章另一个例子。

人们经常进行隐式转换和旧代码的另一种方法是使用<!> quot; string <!> quot;存储二进制数据。在这种情况下,它们实际上需要字节,但数据类型需要字符。 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> inc dec 来更改其长度。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top