CharInSet 不适用于非英文字母?

发布于 2024-10-03 18:28:13 字数 819 浏览 3 评论 0原文

我已经将应用程序从 Delphi 2007 更新到 Delphi 2010,一切都很顺利,除了一条编译正常但不起作用的语句:

If Edit1.Text[1] in ['S','س'] then 
  ShowMessage('Found')
else
  ShowMessage('Not Found')

但是,我知道不会,所以我更改为 CharInSet

If CharinSet(Edit1.Text[1],['S','س']) then
  ShowMessage('Found')
else
  ShowMessage('Not Found')

但是当字符串为 S 时,它永远不会工作,但总是与 S 一起工作,即使我投射了 edt1.Text1 使用 AnsiChar 它总是无法使用阿拉伯字母。

我做错了什么,或者这不是 CharInSet 的工作方式?或者这是 CharinSet 中的错误?

更新:

我的好朋友Issam Ali提出了另一个效果很好的解决方案:

  If CharinSet(AnsiString(edt1.Text)[1],['S','س']) then

I have updated an application from Delphi 2007 to Delphi 2010, everything went fine, except one statement that compiled fine but not working which is:

If Edit1.Text[1] in ['S','س'] then 
  ShowMessage('Found')
else
  ShowMessage('Not Found')

However, I knew that in will not, so I changed to CharInSet

If CharinSet(Edit1.Text[1],['S','س']) then
  ShowMessage('Found')
else
  ShowMessage('Not Found')

but it never worked when the string is س, but always work with S, even I cast the edt1.Text1 with AnsiChar it always not work Arabic letters.

Am doing anything wrong, or it's not the way CharInSet works?, or that's a bug in CharinSet?

UPDATE:

My Great friend Issam Ali has suggested another solution which's worked fine as it :

  If CharinSet(AnsiString(edt1.Text)[1],['S','س']) then

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

最单纯的乌龟 2024-10-10 18:28:13

CharInSet 对于 255 以上的字符没有用。在您的情况下,您应该使用

  case C of
    'S','س' : ShowMessage('Found');
  end;

CharInSet is useless for the characters above 255. In your case you should use

  case C of
    'S','س' : ShowMessage('Found');
  end;
戈亓 2024-10-10 18:28:13

发生这种情况是因为 set of char 结构类型(最多限制为 256 个元素)根本不支持 Unicode。也就是说,任何字符 Ord(ch) > 都可以。 High(AnsiChar) 在集合构造函数中被截断,并发出有关将 WideChar 缩小为 AnsiChar 的警告 W1061。看下面的测试用例:

  { naturally, fails, emits CharInSet() suggestion }
  Result := 'س' in ['S','س'];

  { fails because second argument is set of AnsiChar }
  Result := CharInSet(
    'س',
    ['S','س']
  );

  { workaround for WideChar in AnsiCharSet, fails }
  Result := WideStrUtils.InOpSet(
    'س',
    ['S','س']
  );

  { a syntactical workaround, which finally works }
  Result := WideStrUtils.InOpArray(
    'س',
    ['S','س']
  );

  if Result then
    ShowMessage('PASS')
  else
    ShowMessage('FAIL');

This happens because set of char structured type (limited to 256 elements maximum) doesn't support Unicode at all. That is, any characters Ord(ch) > High(AnsiChar) being truncated in the set constructor and warning W1061 about narrowing WideChar to AnsiChar is being emitted. Look at the following testcase:

  { naturally, fails, emits CharInSet() suggestion }
  Result := 'س' in ['S','س'];

  { fails because second argument is set of AnsiChar }
  Result := CharInSet(
    'س',
    ['S','س']
  );

  { workaround for WideChar in AnsiCharSet, fails }
  Result := WideStrUtils.InOpSet(
    'س',
    ['S','س']
  );

  { a syntactical workaround, which finally works }
  Result := WideStrUtils.InOpArray(
    'س',
    ['S','س']
  );

  if Result then
    ShowMessage('PASS')
  else
    ShowMessage('FAIL');
っ〆星空下的拥抱 2024-10-10 18:28:13

此外。

集合仅限于 256 个元素的序数值。所以 AnsiChar 适合,而 (Unicode)Char 不适合。
您可以使用 CharInSet 将 Delphi 的预 unicode 版本移植到 unicode 版本。由于集合的限制,集合对于字符来说不再非常有用。

这背后的原因是集合是作为位掩码实现的。您可以自由地实现您自己的集合版本。例如:

type
  TSet<T> = class 
  public
    procedure Add(const AElem: T);
    function InSet(const AElem: T): Boolean;
  end;

In addition.

sets are limited to ordinal values of 256 elements. So AnsiChar fits and (Unicode)Char does not fit.
You can use CharInSet to port pre unicode versions of Delphi to the unicode versions. Because of the set limitation, sets are not extremely usefull anymore with Chars.

The reason behind this, is that sets are implemented as bitmasks. You are free to implement your own version of a set. For example:

type
  TSet<T> = class 
  public
    procedure Add(const AElem: T);
    function InSet(const AElem: T): Boolean;
  end;
佼人 2024-10-10 18:28:13

使用 TCharHelper.IsInArray 如下:

if Edit1.Text[1].IsInArray(['S','س']) then 
  ShowMessage('Found')
else
  ShowMessage('Not Found');

Use TCharHelper.IsInArray as follows:

if Edit1.Text[1].IsInArray(['S','س']) then 
  ShowMessage('Found')
else
  ShowMessage('Not Found');

您是否将源文件的编码设置为 UTF-8(右键单击打开上下文菜单)? (默认为 ANSI iirc,这不起作用。)

Have you set the encoding of your source file to UTF-8 (right click to open the context menu)? (The default is ANSI iirc, which would not work.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文