Why won't Delphi 2009 let me Include a Char in a set?

本秂侑毒 提交于 2019-12-11 10:43:24

问题


Here is another question about convert old code to D2009 and Unicode. I'm certain that there is simple but i don't see the solution... CharacterSet is a set of Char and s[i] should also be a Char. But the compiler still think there is a conflict between AnsiChar and Char.

The code:

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;  

回答1:


There is no good and simple answer to the question (the reason is already given by Mason). The good solution is to reconsider the algoritm to get rid off "set of char" type. The quick and dirty solution is to preserve ansi chars and strings:

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:


Because a Pascal set can't have a range higher than 0..255, the compiler quietly converts sets of chars to sets of AnsiChars. That's what's causing trouble for you.




回答3:


Delphi does not support sets of Unicode characters. You can only use AnsiChar in a set, but that's not big enough to fit all the possible characters your string might hold.

Instead of Delphi's native set type, though, you can use the TBits type.

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;

A TBits object automatically expends to accommodate the highest bit it needs to represent.

Other changes I made to your code include using the new "for-in" loop style, and the new Character unit for dealing with Unicode characters.



来源:https://stackoverflow.com/questions/2124069/why-wont-delphi-2009-let-me-include-a-char-in-a-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!