CharInSet не работает с неанглийскими буквами?
я обновил приложение от 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
, даже я бросил edt1.Текст1 С AnsiChar у нее всегда не работают арабские буквы.
я делаю что-то неправильно, или это не так CharInSet
работает? или это ошибка в CharinSet
?
обновление:
мой большой друг Иссам Али предложил другое решение, которое отлично сработало:
If CharinSet(AnsiString(edt1.Text)[1],['S','س']) then
5 ответов
CharInSet бесполезен для символов выше 255. В вашем случае вы должны использовать
case C of
'S','س' : ShowMessage('Found');
end;
это происходит потому, что set of char
структурированный тип (не более 256 элементов) вообще не поддерживает Unicode. То есть любые символы Ord(ch) > High(AnsiChar)
усекается в конструкторе набора и выдается предупреждение W1061 об сужении WideChar до AnsiChar. Посмотрите на следующий пример:
{ 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');
дополнительно.
наборы ограничены порядковыми значениями 256 элементов. Таким образом, AnsiChar подходит и (Unicode)Char не подходит. Вы можете использовать CharInSet для переноса pre unicode версий Delphi в версии unicode. Из-за ограничения набора наборы больше не очень полезны с символами.
причина этого заключается в том, что наборы реализуются как битовые маски. Вы можете реализовать свою собственную версию набора. Например:
type
TSet<T> = class
public
procedure Add(const AElem: T);
function InSet(const AElem: T): Boolean;
end;
вы установили кодировку исходного файла в UTF-8
(щелкните правой кнопкой мыши, чтобы открыть контекстное меню)? (По умолчанию используется ANSI iirc, который не будет работать.)
использовать TCharHelper.IsInArray следующим образом:
if Edit1.Text[1].IsInArray(['S','س']) then
ShowMessage('Found')
else
ShowMessage('Not Found');