Note that there are some explanatory texts on larger screens.

plurals
  1. POIs System.Pos in Delphi Flawed?
    text
    copied!<h1>Problem</h1> <p>If the text in TRichEdit is something like this;</p> <pre><code>'hello, world'#$D#$A </code></pre> <p>Then the following routine displays TRUE. However when the RichEdit has </p> <pre><code>'test'#$D#$A#$D#$A'test'#$D#$A#$D#$A'test'#$D#$A </code></pre> <p>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?</p> <pre><code>procedure TForm1.Button1Click(Sender: TObject); var sTmp : String; begin sTmp := RichEdit1.Lines.GetText; if ( ( Pos( ',', sTmp ) &lt;&gt; 0 ) or ( Pos( '"', sTmp ) &lt;&gt; 0 ) or ( Pos( '\n', sTmp ) &lt;&gt; 0 ) or ( Pos( '\r', sTmp ) &lt;&gt; 0 ) ) then Label1.Caption := 'TRUE' else Label1.Caption := 'FALSE'; end; </code></pre> <h1>Workaround - Andreas' Version (Faster Depending on Input)</h1> <pre><code>function CheckChars( const sData: String ): Boolean; var pCur : PChar; begin pCur := PChar( sData ); // Exit at NULL terminator while ( pCur^ &lt;&gt; #0 ) do begin case pCur^ of #13, #10, #34, #44 : Exit(true); end; Inc( pCur ); end; end; </code></pre> <h1>Correct Usage</h1> <pre><code>function CheckChars( const sData: String ): Boolean begin if ( ( Pos( #44, sData ) &lt;&gt; 0 ) or ( Pos( #34, sData ) &lt;&gt; 0 ) or ( Pos( #13, sData ) &lt;&gt; 0 ) or ( Pos( #10, sData ) &lt;&gt; 0 ) ) then Result := true else Result := false; end; </code></pre> <p>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. </p> <h1>Solution</h1> <p>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. </p> <p><em>HOWEVER!</em></p> <p>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. </p> <p>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.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload