Почему Delphi 2009 не позволяет мне включать Char в набор? - PullRequest
1 голос
/ 23 января 2010

Вот еще один вопрос о преобразовании старого кода в 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 ]

4 голосов
/ 23 января 2010

Поскольку набор Паскаля не может иметь диапазон выше 0..255, компилятор тихо преобразует наборы символов в наборы AnsiChars. Вот что доставляет вам неприятности.

3 голосов
/ 23 января 2010

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 автоматически расширяется, чтобы вместить самый высокий бит, который он должен представлять.

Другие изменения, которые я внес в ваш код, включают использование нового стиля цикла "for-in" и нового символа для работы с символами Юникода.

3 голосов
/ 23 января 2010

Нет хорошего и простого ответа на вопрос (причина уже указана Мэйсоном). Хорошее решение - пересмотреть алгоритм, чтобы избавиться от типа «набор символов». Быстрое и грязное решение заключается в сохранении 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;  
...