为什么Delphi 2009不让我在集合中包含一个字符?

为什么Delphi 2009不让我在集合中包含一个字符?,delphi,unicode,delphi-2009,Delphi,Unicode,Delphi 2009,下面是关于将旧代码转换为D2009和Unicode的另一个问题。我确信这很简单,但我看不出解决办法。。。 CharacterSet是一组字符,s[i]也应该是一个字符。 但是编译器仍然认为AnsiChar和Char之间存在冲突 守则: TSetOfChar = Set of Char; procedure aFunc; var CharacterSet: TSetOfChar; s: String; j: Integer; CaseSensitive: Boolean; beg

下面是关于将旧代码转换为D2009和Unicode的另一个问题。我确信这很简单,但我看不出解决办法。。。 CharacterSet是一组字符,s[i]也应该是一个字符。 但是编译器仍然认为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;  

因为Pascal集的范围不能大于0..255,编译器会悄悄地将字符集转换为AnsiChars集。这就是给您带来麻烦的原因。

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

这个问题没有简单的好答案,梅森已经给出了原因。好的解决方案是重新考虑去除字符类型偏移的算法。快速而肮脏的解决方案是保留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;  

这个问题没有简单的好答案,梅森已经给出了原因。好的解决方案是重新考虑去除字符类型偏移的算法。快速而肮脏的解决方案是保留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;  

Delphi不支持Unicode字符集。您只能在一个集合中使用AnsiChar,但它不够大,无法容纳字符串可能包含的所有字符

但是,您可以使用该类型来代替Delphi的本机集合类型

TBits对象自动扩展以容纳它需要表示的最高位


我对您的代码所做的其他更改包括使用和处理Unicode字符的新单元。

Delphi不支持Unicode字符集。您只能在一个集合中使用AnsiChar,但它不够大,无法容纳字符串可能包含的所有字符

但是,您可以使用该类型来代替Delphi的本机集合类型

TBits对象自动扩展以容纳它需要表示的最高位


我对您的代码所做的其他更改包括使用,以及处理Unicode字符的新单元。

我不确定这个问题是否真的意味着所有widechar类型的集合的构造。更可能的是,作者实际上使用的是所有unicode字符的一小部分。输入类型是unicode。我们还没有被告知它只保存当前代码页中的字符。不管子集有多小,它是否也是AnsiChar的子集都无关紧要。非常方便的想法。如果你真的需要一个65K位的数组,它可以很好地工作,并且自动扩展以填充你实际使用的代码点的数量意味着你不必预先分配到16位。另外要记住的是Unicode Destring是基于UTF-16的,UTF-16使用两个字符的代理作为Unicode代码点的子集。为了在政治上正确,您应该在处理字符集之前将UTF-16解码为UTF-32。TCharacter类有处理UTF-32代码点和UTF-16代理的方法。我不确定这个问题是否真的意味着所有widechar类类型集合的构造。更可能的是,作者实际上使用的是所有unicode字符的一小部分。输入类型是unicode。我们还没有被告知它只保存当前代码页中的字符。不管子集有多小,它是否也是AnsiChar的子集都无关紧要。非常方便的想法。如果你真的需要一个65K位的数组,它可以很好地工作,并且自动扩展以填充你实际使用的代码点的数量意味着你不必预先分配到16位。另外要记住的是Unicode Destring是基于UTF-16的,UTF-16使用两个字符的代理作为Unicode代码点的子集。为了在政治上正确,您应该在处理字符集之前将UTF-16解码为UTF-32。TCharacter类有处理UTF-32代码点和UTF-16代理的方法。哇,这是一些奇怪的行为。A肯定希望编译器在这里给出错误。当所有其他转换导致编译器警告时,为什么在这里安静?哇,这是一些奇怪的行为。A肯定希望编译器在这里给出错误。当所有其他转换都导致编译器警告时,为什么要在这里安静地进行?