我正在尝试使一些String处理例程兼容 最新的delphi版本。我正在使用Delphi2005和2007,但我不完全确定兼容性。
以下是一些示例,它们是否与旧字符串类型兼容? (我将使用一个虚构的STRING_UNICODE指令)。
类型定义:
{$IFNDEF UNICODE_STRING}
TextBuffer = Array[0..13] Of Char;
{$ELSE}
TextBuffer = Array[0..13] Of WideChar;
{$ENDIF}
无用与否?在Unicode字符串之前是Char类型(成为什么)WideChar,还是存在差异?
一个功能:
Function RemoveBlanks(Text: String): String;
Var
i: integer;
Begin
result := '';
For i:= 0 To Length(Text) Do
Begin
{$IFNDEF UNICODE_STRING}
If Byte(Text[i]) < 21 Then Continue;
{$ELSE}
If Word(Text[i]) < 21 Then Continue;
{$ENDIF}
If Text[i] = ' ' Then Continue;
Result := Result + Text[i];
End;
Word()投射是否正常?
此处还存在' '
问题。如何处理空间
在Unicode版本?我是否也应该使用该指令
区分' '
和' '
或自动处理' '
作为一个2字节的空白?
跳线:
NewLineBegin := CanReadText( aPTextBuffer, #13#10 );
如何在Unicode版本中解释第二个参数(#13#10
)?它兼容吗?它会被转换为字节块00130010
吗?如果没有,那么该指令是否应该使用常量#0013#0010
?
答案 0 :(得分:7)
首先要做的是阅读MarcoCantú的论文 Unicode:http://edn.embarcadero.com/article/38980
问题1
只使用Char而没有条件代码,它将在旧的和新的。
Char是一种特殊类型,在旧版本的Delphi中是8位类型,在新的Unicode版本中是16位类型。
问题2
Char是一种序数类型,因此您可以编写if s[i]<#21
。
您还需要为字符串启动循环,因为它们使用基于1的索引。
问题3
不需要写#0013,#13很好。
简而言之,几乎所有编写良好的代码都不需要更改。
答案 1 :(得分:1)
一般来说,我建议你非常警惕编译器指令。它们用于他们的目的,但是对于一般用途,它们应该完全避免。
第一个问题是你必须编译你的应用程序并测试它两次,因为它对于指令开/关是根本和/或微妙的不同。
这种情况对于每个附加指令都会变得更糟,因为您通常必须置换组合:
D1开,D2开
D1打开,D2关闭
D1关,D2开
D1关闭,D2关闭
3个指令是8个排列......等等。
请参阅:Get ready for Delphi 2009 and up when developing with Delphi 7?
它有一些很好的答案供您考虑。
如上所述,我建议不要这样做。在回答上述问题时,我也提出反对意见。
更具体地说:
由于与问题1相同的原因,不仅建议这种病,但实际上它有一些微妙的问题。
更精确的Text
(字符串)类型由您的Delphi版本决定。所以:
此外,还有一些特殊注意事项,以及“特殊”字符的新支持类。你会想看看那些。请参阅:How to identify unicode keys on key press?
我很确定#13将被视为单个字符,因此在Delphi&gt; = 2009中 Char == WideChar,字符将占用2个字节。
然而,再次在Delphi中查找Linebreak
常量。 System.sLinebreak
可能是在Kylix时代引入的。
答案 2 :(得分:1)
通用类型 Char
变为基本类型 AnsiChar
或基本类型 WideChar(阅读通用vs 。基本类型)。顺便说一句,你已经有了UNICODE符号$ DEFINEd,但是根本不需要分支,直到需要特定的字节大小。
第二部分闻起来,完全划伤。这是对类型转换的滥用,并且需要人为地进行条件编译。要获得给定Char
的无符号整数字符代码,请使用Ord()
函数(或者如在其他答案中所述 - 使用Char类型的序数特征)。
对于第三部分,字符常量已经是通用类型Char。同样,无需担心,#13
变为字节大小$0D
或字大小$0D00
(请记住小小的结尾)