I need to verify if a certain position in a string is part of a given valid charset. My code does not compile, how to iterate through set of char?
function Valid_Char_at_Index(const CheckStr: string; CheckPos : Integer ; ValidNextChars: TSysCharSet)
: boolean;
var
mychar : Char;
begin
Result := false;
for each mychar in ValidNextChars do
if (CheckStr(Length(CheckStr)) =mychar ) then
Result:= True;
end;
CodePudding user response:
You don't need to iterate. Use CharInSet()
.
function Valid_Char_at_Index(const CheckStr: string; CheckPos : Integer ; ValidNextChars: TSysCharSet)
: boolean;
begin
Result := CharInSet(CheckStr[CheckPos],ValidNextChars);
end;
CodePudding user response:
First, it is not clear why you would expect for each
to work at all, since Delphi doesn't have for each
loops, as stated in the documentation. The documentation or a simple WWW search reveals that the corresponding Delphi concept is the for in
loop.
Second, I don't understand at all what you mean by CheckStr(Length(CheckStr)) = mychar
. Surely the predicate needs to contain the character index? And this is a syntax error, since CheckStr
isn't a function or type. In fact, you simply want to check if the CheckPos
th character of CheckStr
is mychar
.
Putting all this together, we end up with
function CheckCharAt(const AText: string; APos: Integer; ValidChars: TSysCharSet): Boolean;
var
ValidChar: Char;
begin
for ValidChar in ValidChars do
if AText[APos] = ValidChar then
Exit(True);
Result := False;
end;
But please note that this only works for ASCII (and 8-bit character sets), so basically non-typographic English only, because of the TSysCharSet
being a set of AnsiChar
-- and a set of WideChar
being an impossible type (since SizeOf(WideChar) = 2 > 1
).
A simple way to fix this is to use an array of characters instead:
function CheckCharAt(const AText: string; APos: Integer; const ValidChars: array of Char): Boolean;
begin
for var ValidChar in ValidChars do
if AText[APos] = ValidChar then
Exit(True);
Result := False;
end;
But in modern Delphi versions, you don't need to write your own function at all, since you can simply use the TCharHelper.IsInArray
method:
'test'[2].IsInArray(['a', 'e'])
Bonus info: If you only work with AnsiString
s (or ASCII-only string
s), you should of course use the in
set operator:
function CheckCharAt(const AText: AnsiString; APos: Integer; const ValidChars: TSysCharSet): Boolean;
begin
Result := AText[APos] in ValidChars;
end;
But, as I stated above, a set of WideChar
is not possible, so you have to abandon the entire set
concept if you need more than 8-bit characters.