Problem
If the text in TRichEdit is something like this;
'hello, world'#$D#$A
Then the following routine displays TRUE. However when the RichEdit has
'test'#$D#$A#$D#$A'test'#$D#$A#$D#$A'test'#$D#$A
Then the routine displays FALSE. It seems to me to be flawed as it is finding the comma's but not the newlines/linefeeds. I created a workaround to walk the string instead and find what I'm looking for but am still really curious why the Delphi function doesn't work. Any ideas?
procedure TForm1.Button1Click(Sender: TObject);
var
sTmp : String;
begin
sTmp := RichEdit1.Lines.GetText;
if ( ( Pos( ',', sTmp ) <> 0 ) or
( Pos( '"', sTmp ) <> 0 ) or
( Pos( '\n', sTmp ) <> 0 ) or
( Pos( '\r', sTmp ) <> 0 ) ) then
Label1.Caption := 'TRUE'
else
Label1.Caption := 'FALSE';
end;
Workaround - Andreas' Version (Faster Depending on Input)
function CheckChars( const sData: String ): Boolean;
var
pCur : PChar;
begin
pCur := PChar( sData );
// Exit at NULL terminator
while ( pCur^ <> #0 ) do
begin
case pCur^ of
#13, #10, #34, #44 : Exit(true);
end;
Inc( pCur );
end;
end;
Correct Usage
function CheckChars( const sData: String ): Boolean
begin
if ( ( Pos( #44, sData ) <> 0 ) or
( Pos( #34, sData ) <> 0 ) or
( Pos( #13, sData ) <> 0 ) or
( Pos( #10, sData ) <> 0 ) ) then
Result := true
else
Result := false;
end;
Works for all characters tested, I decided not to mix quoted chars and decimal chars for readability. The only question now is which is quicker? I think my workaround would be quicker since I'm checking each char against all the ones I'm looking for, whereas when I use the System.Pos function I am running the same parsing routine 4 times.
Solution
After some testing, it depends on what kind of characters you are looking for. Testing this with a comma(#44), located 294k characters into a 589k length string. The function using System.Pos has a performance of ~390 microseconds, and the case statement runs ~700 microseconds.
HOWEVER!
If you change the character in the string to a Linefeed(#10) then it takes much much longer for the System.Pos(~2700 microseconds) due to the repeated calls. The case statement still runs ~700 microseconds.
So I guess if your looking for a particular character then System.Pos is definitely the way to go, however if you are looking for multiple(which my app does) then a repeated call isn't necessary when you could just scan it and use the case statement.