繁体   English   中英

解决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
      if not CaseSensitive then
      begin
        Include(CharacterSet, AnsiUpperCase(s[j])[1]);  // Error E2010
        Include(CharacterSet, AnsiLowerCase(s[j])[1])   // Error E2010
      end
    end;

有解决方案的建议吗? 我认为处理AnsiStrings就足够了。

Delphi集的基本类型最多可以包含256个元素。 这意味着您的集合实际上实际上set of AnsiChar

而且您的代码失败,因为AnsiUpperCase(s[j])string类型为UnicodeString 因此, AnsiUpperCase(s[j])[1]的类型为char ,它是WideChar 编译器试图告诉您的是什么。 尽管名称相同,但AnsiUpperCaseAnsiLowerCase运行,并返回UnicodeString

如果您确实仍然想使用ANSI字符串,则需要使用AnsiStrings单元中的AnsiUpperCaseAnsiLowerCase函数。 这些版本在上运行,并返回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同样AnsiLowerCase 或者,您可以使用CharUpperBuffCharLowerBuff避免堆分配。

当然,还有整个Unicode问题。 您正在使用Unicode Delphi,但仅限于ANSI。 您真的要这么做吗? 恐怕如果您想支持Unicode,则必须停止使用Delphi集。 您将需要一种可以支持宽字符集的数据类型。 您可能还需要考虑如何处理多字节UTF-16字符。

  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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM