解决E2010不兼容的类型:'AnsiChar'和'Char' [英] Solve E2010 Incompatible types: 'AnsiChar' and 'Char'
问题描述
我尝试将一些代码从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
如果不是CaseSensitive,那么
begin
Include(CharacterSet,AnsiUpperCase(s [j])[1]); // Error E2010
Include(CharacterSet,AnsiLowerCase(s [j])[1])// Error E2010
end
end;
解决方案的任何建议?我认为它是足够的来处理AnsiStrings。
Delphi集的基本类型最多可以有256个元素。这意味着你的套件实际上真的是安装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]);
如果不是CaseSensitive然后
begin
Include(CharacterSet,AnsiUpperCase(AnsiStr [j])[1]);
Include(CharacterSet,AnsiLowerCase(AnsiStr [j])[1])$ b $ b end
end;
当然,创建包含单个字符的字符串看起来效率很低。当然,您可以找到一种方法来执行此操作,而无需使用堆分配的字符串并直接对字符进行操作。
明显的改进是调用 AnsiUpperCase
一次,传递整个字符串,并迭代返回的大写字符串。对于 AnsiLowerCase
也是如此。或者您可以使用 CharUpperBuff
和 CharLowerBuff
以避免堆分配。
当然,Unicode还有整个问题。您正在使用Unicode Delphi,但仅限于ANSI。你真的想这样做吗?如果你想支持Unicode,那么你必须停止使用Delphi集,恐怕。您将需要能够支持广泛字符集的数据类型。您还可能需要考虑如何处理多字节UTF-16字符。
I try to convert some code from D2007 to XE5 and got
E2010 Incompatible types: 'AnsiChar' and 'Char'
from this code
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;
Any suggestion for solution ? I think it is enough to handle AnsiStrings.
The base type for a Delphi set can have at most 256 elements. Which means that your set is in fact really set of AnsiChar
.
And your code is failing because AnsiUpperCase(s[j])
is of type string
which is UnicodeString
. Hence AnsiUpperCase(s[j])[1]
is of type char
which is WideChar
. Which is what the compiler is trying to tell you. Despite their names, AnsiUpperCase
and AnsiLowerCase
operate on, and return UnicodeString
.
If you really do still want to work with ANSI strings then you will need to use the AnsiUpperCase
and AnsiLowerCase
functions from the AnsiStrings
unit. These versions operate on, and return AnsiString
. Add that unit to your uses clause, and make sure you pass AnsiString
values:
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;
Of course, it seems extremely inefficient to be creating strings containing single characters. Surely you can find a way to do this without using heap allocated strings and operating directly on characters.
An obvious improvement would be to call AnsiUpperCase
once, passing the entire string, and iterate over the upper case string returned. Likewise for AnsiLowerCase
. Or you could use CharUpperBuff
and CharLowerBuff
to avoid heap allocations.
And of course there's the whole issue of Unicode. You are using a Unicode Delphi but being confined to ANSI. Do you really want to do that? If you want to support Unicode then you have to stop using Delphi sets, I am afraid. You'll need a data type that can support sets of wide characters. You would also perhaps need to consider what to do with multi-byte UTF-16 characters.
这篇关于解决E2010不兼容的类型:'AnsiChar'和'Char'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!