解决E2010不兼容的类型:'AnsiChar'和'Char' [英] Solve E2010 Incompatible types: 'AnsiChar' and 'Char'

查看:1015
本文介绍了解决E2010不兼容的类型:'AnsiChar'和'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
如果不是CaseSensitive,那么
begin
Include(CharacterSet,AnsiUpperCase(s [j])[1]); // Error E2010
Include(CharacterSet,AnsiLowerCase(s [j])[1])// Error E2010
end
end;

解决方案的任何建议?我认为它是足够的来处理AnsiStrings。

解决方案

Delphi集的基本类型最多可以有256个元素。这意味着你的套件实际上真的是安装AnsiChar



你的代码失败,因为 AnsiUpperCase(s [j])类型为 string 这是 UnicodeString 。因此 AnsiUpperCase(s [j])[1] char 的类型 WideChar 。编译器试图告诉你的是什么。尽管他们的名字, AnsiUpperCase AnsiLowerCase 操作,并返回 UnicodeString



如果您确实仍然希望使用ANSI字符串,那么您将需要使用 AnsiUpperCase AnsiLowerCase 函数从 AnsiStrings 单位。这些版本运行并返回 AnsiString 。将该单元添加到您的uses子句中,并确保您通过 AnsiString 值:

  var 
AnsiStr:AnsiString;
....
AnsiStr:= AnsiString(s);
for j:= 1 to Length(AnsiStr)do
begin
Include(CharacterSet,AnsiStr [j]);
如果不是CaseSensitive然后
begin
Include(CharacterSet,AnsiUpperCase(AnsiStr [j])[1]);
Include(CharacterSet,AnsiLowerCase(AnsiStr [j])[1])$ ​​b $ b end
end;

当然,创建包含单个字符的字符串看起来效率很低。当然,您可以找到一种方法来执行此操作,而无需使用堆分配的字符串并直接对字符进行操作。



明显的改进是调用 AnsiUpperCase 一次,传递整个字符串,并迭代返回的大写字符串。对于 AnsiLowerCase 也是如此。或者您可以使用 CharUpperBuff CharLowerBuff 以避免堆分配。



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


I try to convert some code from D2007 to XE5 and got

E2010 Incompatible types: 'AnsiChar' and 'Char'

from this code

  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;

Any suggestion for solution ? I think it is enough to handle AnsiStrings.

解决方案

The base type for a Delphi set can have at most 256 elements. Which means that your set is in fact really set of AnsiChar.

And your code is failing because AnsiUpperCase(s[j]) is of type string which is UnicodeString. Hence AnsiUpperCase(s[j])[1] is of type char which is WideChar. Which is what the compiler is trying to tell you. Despite their names, AnsiUpperCase and AnsiLowerCase operate on, and return UnicodeString.

If you really do still want to work with ANSI strings then you will need to use the AnsiUpperCase and AnsiLowerCase functions from the AnsiStrings unit. These versions operate on, and return AnsiString. Add that unit to your uses clause, and make sure you pass AnsiString values:

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;

Of course, it seems extremely inefficient to be creating strings containing single characters. Surely you can find a way to do this without using heap allocated strings and operating directly on characters.

An obvious improvement would be to call AnsiUpperCase once, passing the entire string, and iterate over the upper case string returned. Likewise for AnsiLowerCase. Or you could use CharUpperBuff and CharLowerBuff to avoid heap allocations.

And of course there's the whole issue of Unicode. You are using a Unicode Delphi but being confined to ANSI. Do you really want to do that? If you want to support Unicode then you have to stop using Delphi sets, I am afraid. You'll need a data type that can support sets of wide characters. You would also perhaps need to consider what to do with multi-byte UTF-16 characters.

这篇关于解决E2010不兼容的类型:'AnsiChar'和'Char'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆