6

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

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

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

谢谢你的帮助!霍尔格

4

7 回答 7

5

使用 Unicode SizeOf(SomeChar) <> Length(SomeChar)。本质上,字符串的长度小于其char大小的总和。只要您不假设SizeOf(Char) = 1SizeOf(SomeString[x]) = 1(因为现在两者都是FALSE)或尝试将bytechar互换,那么您应该没有任何麻烦. 任何你在做一些创造性的事情的地方Byte s 到Char s 或String s 中,那么你将需要使用AnsiString

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

于 2008-09-24T16:20:03.350 回答
4

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

人们经常进行这种隐式转换和旧代码的另一种方法是使用“字符串”来存储二进制数据。在这种情况下,他们实际上需要字节,但数据类型需要字符。D2009 有一个更好的类型

于 2008-09-24T12:26:00.777 回答
1

我没有尝试过 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 之前,这两个值是相等的)

于 2008-09-24T08:48:57.270 回答
0

字符的实际大小无关紧要,除非您在字节级别进行操作。

于 2008-09-24T08:43:32.057 回答
0

(当然,如果我使用字符串作为字符串而不存储任何其他数据)

这是关键点,您不会将字符串用于其他目的,但有些人会这样做。他们像数组一样使用字符串,所以他们(包括我在内)需要检查所有这些用途以确保没有任何东西被破坏......

于 2008-09-24T08:45:49.323 回答
0

不要忘记,有时这种转换并不是真正需要的。例如,将 GUID 存储在记录中。guid 只能包含十六进制字符加上 - 和括号......使它们占用两倍的空间会对现有代码产生相当大的影响。当然,简单的解决方案是将它们更改为 AnsiString,并在对它们进行任何字符串操作时处理编译器警告。

于 2008-09-24T13:11:35.253 回答
0

如果您进行 Windows API 调用,这可能是一个问题。或者,如果您有使用incdec of str[0]来更改其长度的遗留代码。

于 2015-06-28T06:38:34.180 回答