我尝试将一些代码从D2007转换为XE5并获得
E2010不兼容的类型:'AnsiChar'和'Char'
来自此代码
TSetOfChar = Set of Char;
var
CharacterSet: TSetOfChar;
s: String;
for j := 1 to Length(s) do
begin
Include(CharacterSet, s[j]); // Error E2010
if not CaseSensitive then
begin
Include(CharacterSet, AnsiUpperCase(s[j])[1]); // Error E2010
Include(CharacterSet, AnsiLowerCase(s[j])[1]) // Error E2010
end
end;
有任何解决方案的建议吗?我认为这足以处理AnsiStrings。
答案 0 :(得分:2)
Delphi集的基本类型最多可包含256个元素。这意味着您的集合实际上是set of AnsiChar
。
您的代码失败,因为AnsiUpperCase(s[j])
的类型为string
UnicodeString
。因此,AnsiUpperCase(s[j])[1]
的类型为char
,即WideChar
。这是编译器试图告诉你的内容。尽管名称如此,AnsiUpperCase
和AnsiLowerCase
仍然有效,并返回UnicodeString
。
如果您确实仍想使用ANSI字符串,则需要使用AnsiUpperCase
单元中的AnsiLowerCase
和AnsiStrings
函数。这些版本运行,并返回AnsiString
。将该单元添加到uses子句中,并确保传递AnsiString
值:
var
AnsiStr: AnsiString;
....
AnsiStr := AnsiString(s);
for j := 1 to Length(AnsiStr) do
begin
Include(CharacterSet, AnsiStr[j]);
if not CaseSensitive then
begin
Include(CharacterSet, AnsiUpperCase(AnsiStr[j])[1]);
Include(CharacterSet, AnsiLowerCase(AnsiStr[j])[1])
end
end;
当然,创建包含单个字符的字符串似乎效率极低。当然,你可以找到一种方法来实现这一点,而无需使用堆分配的字符串并直接在字符上操作。
一个显而易见的改进是调用AnsiUpperCase
一次,传递整个字符串,并迭代返回的大写字符串。同样适用于AnsiLowerCase
。或者您可以使用CharUpperBuff
和CharLowerBuff
来避免堆分配。
当然还有整个Unicode问题。您使用的是Unicode Delphi,但仅限于ANSI。你真的想这么做吗?如果你想支持Unicode,那么你恐怕不得不停止使用Delphi集。您需要一种可以支持宽字符集的数据类型。您可能还需要考虑如何处理多字节UTF-16字符。
答案 1 :(得分:2)
uses
..., AnsiStrings;
type
TSetOfChar = Set of AnsiChar;
var
CharacterSet: TSetOfChar;
s: AnsiString;
for j := 1 to Length(s) do
begin
Include(CharacterSet, s[j])
if not CaseSensitive then
begin
Include(CharacterSet, AnsiStrings.AnsiUpperCase(s[j])[1]);
Include(CharacterSet, AnsiStrings.AnsiLowerCase(s[j])[1]);
end
end;
可替换地:
uses
..., AnsiStrings;
type
TSetOfChar = Set of AnsiChar;
var
CharacterSet: TSetOfChar;
s, s2: AnsiString;
if CaseSensitive then
begin
for j := 1 to Length(s) do
Include(CharacterSet, s[j]);
end else
begin
s2 := AnsiStrings.AnsiUpperCase(s);
for j := 1 to Length(s2) do
Include(CharacterSet, s2[j]);
s2 := AnsiStrings.AnsiLowerCase(s);
for j := 1 to Length(s2) do
Include(CharacterSet, s2[j]);
end
end;