为什么Delphi 2009不允许我在一组中加入Char?

时间:2010-01-23 17:53:39

标签: delphi unicode delphi-2009

这是关于将旧代码转换为D2009和Unicode的另一个问题。我确信这很简单,但我没有看到解决方案...... CharacterSet是一组Char,s [i]也应该是Char。 但是编译器仍然认为AnsiChar和Char之间存在冲突。

代码:

TSetOfChar = Set of Char;

procedure aFunc;
var
  CharacterSet: TSetOfChar;
  s: String;
  j: Integer;
  CaseSensitive: Boolean;
begin
  // Other code that assign a string to s
  // Set CaseSensitive to a value

  CharacterSet := [];
  for j := 1 to Length(s) do
  begin
    Include(CharacterSet, s[j]);  // E2010 Incompatible types: 'AnsiChar' and 'Char'
    if not CaseSensitive then
    begin
      Include(CharacterSet, AnsiUpperCase(s[j])[1]);
      Include(CharacterSet, AnsiLowerCase(s[j])[1])
    end
  end;
end;  

3 个答案:

答案 0 :(得分:4)

因为Pascal集的范围不能超过0..255,编译器会将字符集静默地转换为AnsiChars集。这就是给你带来麻烦的原因。

答案 1 :(得分:3)

对这个问题没有好的和简单的答案(梅森已经给出了原因)。好的解决方案是重新考虑算法以摆脱“一组字符”类型。快速而肮脏的解决方案是保留ansi字符和字符串:

TSetOfChar = Set of AnsiChar;

procedure aFunc;
var
  CharacterSet: TSetOfChar;
  s: String;
  S1, SU, SL: Ansistring;
  j: Integer;
  CaseSensitive: Boolean;
begin
  // Other code that assign a string to s
  // Set CaseSensitive to a value

  S1:= s;
  SU:= AnsiUpperCase(s);
  SL:= AnsiLowerCase(s);
  CharacterSet := [];
  for j := 1 to Length(S1) do
  begin
    Include(CharacterSet, S1[j]);
    if not CaseSensitive then
    begin
      Include(CharacterSet, SU[j]);
      Include(CharacterSet, SL[j]);
    end
  end;
end;  

答案 2 :(得分:3)

Delphi不支持Unicode字符集。你只能在一组中使用AnsiChar,但这不足以容纳你的字符串可能包含的所有可能的字符。

不是使用Delphi的原生集类型,而是使用TBits类型。

procedure aFunc;
var
  CharacterSet: TBits;
  s: String;
  c: Char;
  CaseSensitive: Boolean;
begin
  // Other code that assign a string to s
  // Set CaseSensitive to a value

  CharacterSet := TBits.Create;
  try
    for c in s do begin
      CharacterSet[Ord(c)] := True;
      if not CaseSensitive then begin
        CharacterSet[Ord(Character.ToUpper(c))] := True;
        CharacterSet[Ord(Character.ToLower(c))] := True;
      end
    end;
  finally
    CharacterSet.Free;
  end;
end;

TBits对象会自动消耗以容纳它需要表示的最高位。

我对您的代码所做的其他更改包括使用new "for-in" loop style和新的Character单元来处理Unicode字符。