我刚刚获得Delphi 2009并且之前已经阅读了一些关于由于切换到Unicode字符串而可能需要的修改的文章。 大多数情况下,提到sizeof(char)不再保证为1。 但是为什么这对于字符串操作会很有意思呢?
例如,如果我使用AnsiString:='Test'并对String(现在是unicode)执行相同操作,那么我得到Length()= 4,这对于两种情况都是正确的。 没有测试它,我确信所有其他字符串操作函数的行为方式相同,并在内部决定参数是unicode字符串还是其他任何东西。
如果我进行字符串操作,为什么我会对char的实际大小感兴趣? (当然,如果我使用字符串作为字符串而不存储任何其他数据)
感谢您的帮助! 霍尔格
答案 0 :(得分:5)
使用Unicode SizeOf(SomeChar)<>长度(SomeChar)。基本上字符串的长度小于其字符串的大小总和。只要您不假设 SizeOf(Char)= 1 或 SizeOf(SomeString [x])= 1 (因为两者都 FALSE 现在)或尝试将字节与 char 交换,那么你应该没有任何问题。你正在做字符 s或字符串的创意填充字节的任何地方,那么你需要使用 AnsiString 强>
(SizeOf(SomeString)仍然是4,无论长度如何,因为它本质上是一个带有一些编译器魔法的指针。)
答案 1 :(得分:4)
人们经常在旧的Delphi代码中隐式地将字符转换为字节,而没有真正考虑它。例如,写入流时。将字符串写入流时,必须指定要写入的字节数,但人们通常会传递字符数。有关其他示例,请参阅this post from Chris Bensen。
人们经常进行隐式转换和旧代码的另一种方法是使用“字符串”来存储二进制数据。在这种情况下,它们实际上需要字节,但数据类型需要字符。 D2009有a better type for this。
答案 2 :(得分: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之前,这两个值彼此相等)
答案 3 :(得分:0)
字符的实际大小无关紧要,除非您在字节级别进行操作。
答案 4 :(得分:0)
(当然如果我使用字符串作为字符串而不存储任何其他数据)
这是关键点,你不会将字符串用于其他目的,但有些人会这样做。他们像数组一样使用字符串,所以他们(包括我在内)需要检查所有这些用途,以确保没有任何内容被破坏......
答案 5 :(得分:0)
让我们不要忘记有时候这种转换并不是真正需要的。比如说,将GUID存储在记录中。 guid只能包含十六进制字符加上 - 和括号......使它们占用两倍的空间可以对现有代码产生相当大的影响。当然,简单的解决方案是将它们更改为AnsiString,如果对它们进行任何字符串操作,则处理编译器警告。
答案 6 :(得分:0)
如果您进行Windows API调用,则可能会出现问题。或者,如果您的遗留代码执行 str <0> 的 inc 或 dec 来更改其长度。