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 CheckPosth 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 AnsiStrings (or ASCII-only strings), 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.
