Board index » delphi » Break doesn't work on longer file

Break doesn't work on longer file

 I'm at my wit's end now. If I use the following code on a short
file (297 lines -- 8 KB) it works. If I try it on a longer one
(1981 lines -- 54 KB) the last 'Break' is ignored and the
processing continues giving me a ListIndex error. Any ideas?:
-----

procedure TForm1.Button1Click(Sender: TObject);
var
 posint,num : integer;
 Lista : TStringList;
begin
  num := 0;
  Lista := TStringList.Create;
 try
  Lista.LoadFromFile(progdir +'\sw.txt');
  while num < Lista.Count -1 do
  begin
    repeat
      posint := pos('DATE: ', UpperCase(Lista[num]));
      if posint <> 0 then break;
      inc(num);
    until posint <> 0;

    repeat
      posint := pos('CUSTOM ', UpperCase(Lista[num]));
      if posint <> 0 then break;
      inc(num);
    until posint <> 0;

    if num > Lista.Count -5 then Break;
  end;
  ShowMessage(inttostr(num) +'records processed');
  finally
    Lista.Free;
  end;
end;
-----  
=========================================
Brad Blanchard
BRASER SOFT *** Learn Spanish / Aprender ingls
Website :  http://www.braser.com

 

Re:Break doesn't work on longer file


"GB Blanchard" <gbbNOS...@ctv.es> skrev i melding
news:VA.00001dc3.0044eb97@braser.com...

Quote
> I'm at my wit's end now. If I use the following code on a short
> file (297 lines -- 8 KB) it works. If I try it on a longer one
> (1981 lines -- 54 KB) the last 'Break' is ignored and the
> processing continues giving me a ListIndex error. Any ideas?:
> -----

> procedure TForm1.Button1Click(Sender: TObject);
> var
>  posint,num : integer;
>  Lista : TStringList;
> begin
>   num := 0;
>   Lista := TStringList.Create;
>  try
>   Lista.LoadFromFile(progdir +'\sw.txt');
>   while num < Lista.Count -1 do
>   begin
>     repeat
>       posint := pos('DATE: ', UpperCase(Lista[num]));
>       if posint <> 0 then break;
>       inc(num);
>     until posint <> 0;

>     repeat
>       posint := pos('CUSTOM ', UpperCase(Lista[num]));
>       if posint <> 0 then break;
>       inc(num);
>     until posint <> 0;

>     if num > Lista.Count -5 then Break;
>   end;
>   ShowMessage(inttostr(num) +'records processed');
>   finally
>     Lista.Free;
>   end;
> end;
> -----

You're aware of that break; only breaks out one level ? The break;s inside
the repeat loops jump out of the loop in question, the last break; terminates
the while loop.
BTW, there is a chance the debug info isn't correct. Altering the code
slightly by joining two lines to one or splitting a line into two may fix
this (if that's the problem).
After having break'ed out of the first repeat, you dive into the next repeat
loop - increasing num without checking whether it's a valid index. I guess
that's where the error emerges...

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorge@takethisaway_itte.no (remve the obvious)

Re:Break doesn't work on longer file


On Tue, 09 Oct 2001 18:21:14 +0200, GB Blanchard <gbbNOS...@ctv.es>
wrote:

Quote
> I'm at my wit's end now. If I use the following code on a short
>file (297 lines -- 8 KB) it works. If I try it on a longer one
>(1981 lines -- 54 KB) the last 'Break' is ignored and the
>processing continues giving me a ListIndex error. Any ideas?:

You have those nested loops - the final break being ignored
is not the only way you could get an IndexError. (Is
it really "ListIndex" error?) Whether this code works or
not depends on exactly what's in the file (a file without
a DATE: and then a CUSTOM in the last few lines is going to
give an IndexError regardless of the file size.)

You should really rewrite it to handle invalid file format
better.

Quote
>-----

>procedure TForm1.Button1Click(Sender: TObject);
>var
> posint,num : integer;
> Lista : TStringList;
>begin
>  num := 0;
>  Lista := TStringList.Create;
> try
>  Lista.LoadFromFile(progdir +'\sw.txt');
>  while num < Lista.Count -1 do
>  begin
>    repeat
>      posint := pos('DATE: ', UpperCase(Lista[num]));
>      if posint <> 0 then break;
>      inc(num);
>    until posint <> 0;

>    repeat
>      posint := pos('CUSTOM ', UpperCase(Lista[num]));
>      if posint <> 0 then break;
>      inc(num);
>    until posint <> 0;

>    if num > Lista.Count -5 then Break;
>  end;
>  ShowMessage(inttostr(num) +'records processed');
>  finally
>    Lista.Free;
>  end;
>end;
>-----  
>=========================================
>Brad Blanchard
>BRASER SOFT *** Learn Spanish / Aprender ingls
>Website :  http://www.braser.com

Re:Break doesn't work on longer file


Quote
> You're aware of that break; only breaks out one level ? The break;s inside
> the repeat loops jump out of the loop in question, the last break; terminates
> the while loop.

 That's what I want it to do. But it's not jumping out of the while loop on the
larger file.

Quote
> BTW, there is a chance the debug info isn't correct. Altering the code
> slightly by joining two lines to one or splitting a line into two may fix
> this (if that's the problem).

 Good idea. I'll try that.

Quote
> After having break'ed out of the first repeat, you dive into the next repeat
> loop - increasing num without checking whether it's a valid index. I guess
> that's where the error emerges...

 Since 'CUSTOM' is always the last entry in the fixed-file format, the

  if num > Lista.Count -5 then Break;

 should take care of that, but it doesn't.

=========================================
Brad Blanchard
BRASER SOFT *** Learn Spanish / Aprender ingls
Aptdo. de Correos 555 - Estepona, Mlaga (Spain)
Website :  http://www.braser.com

Re:Break doesn't work on longer file


Quote
> Whether this code works or
> not depends on exactly what's in the file (a file without
> a DATE: and then a CUSTOM in the last few lines is going to
> give an IndexError regardless of the file size.)
> You should really rewrite it to handle invalid file format
> better.

 I agree that it could be better written (whether I could do it
unaided is another story :) , but I left it that way because it's a
fixed-format file, and 'DATE' and 'CUSTOM' will always be present.
Besides, 'CUSTOM' is always the next-to-last entry and that is the
reason for putting the

  if num > Lista.Count -5 then Break;

 at the end.

=========================================
Brad Blanchard
BRASER SOFT *** Learn Spanish / Aprender ingls
Aptdo. de Correos 555 - Estepona, Mlaga (Spain)
Website :  http://www.braser.com

Re:Break doesn't work on longer file


How often does "Date" and "Custom" occur in the file, and how many lines after
the last"Custom" before the EOF. If ther is more than 6 lines between the last
"Custom" and the EOF you would get a list index error.

Have you tried putting assert statements ...

Assert(Num < Count, 'Looking for Date - Num : ' + IntToStr(Num) + ', Count : '
+ IntToStr(Count)); before the Date repeat-until and a similar one with a
changed string for Custom.

This will give you an EAssertionFailed exception when the logical statement is
false, and the string will be displayed in its message.

Might give you some clues.

Alan Lloyd
alangll...@aol.com

Re:Break doesn't work on longer file


Quote
On Wed, 10 Oct 2001 20:24:00 +0200, Brad Blanchard <g...@ctv.es> wrote:
>> Whether this code works or
>> not depends on exactly what's in the file (a file without
>> a DATE: and then a CUSTOM in the last few lines is going to
>> give an IndexError regardless of the file size.)
>> You should really rewrite it to handle invalid file format
>> better.

> I agree that it could be better written (whether I could do it
>unaided is another story :) , but I left it that way because it's a
>fixed-format file, and 'DATE' and 'CUSTOM' will always be present.
>Besides, 'CUSTOM' is always the next-to-last entry and that is the
>reason for putting the

>  if num > Lista.Count -5 then Break;

> at the end.

Having CUSTOM for the next-to-last entry and that
"if num > Lista.Count - 5 then Break;" is not
enough to guarantee the the thing will work
without an IndexError. In fact if _every_ line
in the file is CUSTOM then it's obvious that
you get an IndexError because the first loop,
looking for whatever the other thing is, will
run off the end of the list.

- Show quoted text -

Quote
>=========================================
>Brad Blanchard
>BRASER SOFT *** Learn Spanish / Aprender ingls
>Aptdo. de Correos 555 - Estepona, Mlaga (Spain)
>Website :  http://www.braser.com

Re:Break doesn't work on longer file


Quote
> How often does "Date" and "Custom" occur in the file, and how many lines after
> the last"Custom" before the EOF. If ther is more than 6 lines between the last
> "Custom" and the EOF you would get a list index error.

 You have identified the problem. I feel silly now for not having seen it
before. Once again, thanks Alan.

 I now know how to solve the problem, but would like some advice before I jump
into it:

 What is the fastest way to find the LAST occurence of the word 'Custom' in the
file? Any help will be appreciated.

=========================================
Brad Blanchard
BRASER SOFT *** Learn Spanish / Aprender ingls
Aptdo. de Correos 555 - Estepona, Mlaga (Spain)
Website :  http://www.braser.com

Re:Break doesn't work on longer file


In article <VA.00001dd2.0034a...@braser.com>, Brad Blanchard <g...@ctv.es>
writes:

Quote
> What is the fastest way to find the LAST occurence of the word 'Custom' in
>the
>file? Any help will be appreciated.

Are you wanting this to prevent the other errors, or do you just want to find
only the last occurence.

If the former then I would suggest you reconstruct you search algorithm to
provide protection against list index errors at every search node. If the
latter then just start at the end of the file and work back, decrementing the
list index (but checking to protect against < 0 errors).

You might find it easier/better to use a file or memory stream. You'd have to
read it by byte or use a search algorithm (like Boyer-Morse-Horspool).

 The first thing to do in any case is to clearly identify your strategy for
doing what you want to achieve.

After that coding becomes easy/easier <g>.

Quote
> You have identified the problem. I feel silly now for not having seen it
>before. Once again, thanks Alan.

Don't feel too bad about it - I've just spent some frustrating time bug-hunting
because I had not immediately realised that ...
   (A div 1000) * B * C
 ... was not the same as ...
   (A * B * C) div 1000
.. which latter had suffered from overflow errors and needed changing.
<g>.

Alan Lloyd
alangll...@aol.com

Re:Break doesn't work on longer file


 I appreciate all of your advice Alan. I've got things working now
and you've opened my eyes to a couple of things about programming
which we weren't talking about directly.

=========================================
Brad Blanchard
BRASER SOFT *** Learn Spanish / Aprender ingls
Website :  http://www.braser.com

Other Threads