【问题标题】:Delphi 2009 + Unicode + Char-sizeDelphi 2009 + Unicode + 字符大小
【发布时间】:2010-09-12 16:00:32
【问题描述】:

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

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

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

感谢您的帮助! 霍尔格

【问题讨论】:

    标签: delphi unicode delphi-2009


    【解决方案1】:

    如果您进行 Windows API 调用,可能会出现问题。或者,如果您有旧代码执行 incdec of str[0] 来更改其长度。

    【讨论】:

      【解决方案2】:

      使用 Unicode SizeOf(SomeChar) Length(SomeChar)。本质上,string 的长度小于其 char 大小的总和。只要您不假设 SizeOf(Char) = 1SizeOf(SomeString[x]) = 1(因为两者都是 FALSE now) 或尝试将 bytes 与 chars 互换,那么你应该没有任何问题。任何你在做一些创造性的事情,将 Bytes 填充到 Chars 或 Strings 中,那么你将需要使用 AnsiString强>。

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:

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

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

            【讨论】:

              【解决方案6】:

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

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

              【讨论】:

              • 你是对的。我很困惑,因为我特别阅读了字符串操作,字符大小很重要。当我使用字符串来存储除字符串之外的任何其他内容时,当然要由我来正确处理它。
              【解决方案7】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-01-19
                • 2010-11-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-01-20
                相关资源
                最近更新 更多