Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2006-09

TStringList Bug?

4 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jeremy Cowgar

Below is a simple program that I *think* is working wrong. I am new to Pascal, so I may very well be doing something wrong.

Can anyone comment?

Jeremy

--------------------

program stringlistbug;
uses Classes;
var
	SL : TStringList;
begin
	SL := TStringList.Create;
	SL.Delimiter := '|';
	SL.DelimitedText := 'Hello World|How are you doing?';
	writeln('One ="', SL[0], '"');
	writeln('Two ="', SL[1], '"');
end.

(*
Output:

     $ ./stringlistbug
     One ="Hello"
     Two ="World"

Shouldn't it be:

     $ ./stringlistbug
     One = "Hello World"
     Two = "How are you doing?"

*)

Michael Van Canneyt
to Jeremy Cowgar
Jeremy Cowgar wrote
Below is a simple program that I *think* is working wrong. I am new to Pascal, so I may very well be doing something wrong. Can anyone comment?

Space is always a delimiter.

You should use

SL.DelimitedText := '"Hello World"|"How are you doing?"';

Michael.

Show quoted text 35 lines
Jeremy -------------------- program stringlistbug; uses Classes; var SL : TStringList; begin SL := TStringList.Create; SL.Delimiter := '|'; SL.DelimitedText := 'Hello World|How are you doing?'; writeln('One ="', SL[0], '"'); writeln('Two ="', SL[1], '"'); end. (* Output: $ ./stringlistbug One ="Hello" Two ="World" Shouldn't it be: $ ./stringlistbug One = "Hello World" Two = "How are you doing?" *) _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jeremy Cowgar
to Michael Van Canneyt

I was hoping to use it to parse a pipe delimited file. This will not work as I do not want " chars as part of the result, I'd have to add it in, then subtract them out. That's kind of weird behavior that a delimiter would be forced (space) even when the delimiter field is set.

Thanks for the info though, I'll figure another way.

Jeremy

Michael Van Canneyt wrote 55 lines
On Tue, 26 Sep 2006, Jeremy Cowgar wrote: > Below is a simple program that I *think* is working wrong. I am > new to Pascal, > so I may very well be doing something wrong. > > Can anyone comment? Space is always a delimiter. You should use SL.DelimitedText := '"Hello World"|"How are you doing?"'; Michael. > > Jeremy > > -------------------- > > program stringlistbug; > > uses Classes; > > var > SL : TStringList; > begin > SL := TStringList.Create; > SL.Delimiter := '|'; > SL.DelimitedText := 'Hello World|How are you doing?'; > > writeln('One ="', SL[0], '"'); > writeln('Two ="', SL[1], '"'); > end. > > (* > Output: > $ ./stringlistbug > One ="Hello" > Two ="World" > > Shouldn't it be: > $ ./stringlistbug > One = "Hello World" > Two = "How are you doing?" > *) > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Graeme Geldenhuys
to Jeremy Cowgar
Jeremy Cowgar wrote
Thanks for the info though, I'll figure another way. Jeremy

Try the following approach:

----------------------------------------------
function tiNumToken(const pStrValue, pStrToken : string) : integer;
var
  i, iCount : integer;
  lsValue : string;
begin
  Result := 0;
  if pStrValue = '' then
    Exit; //==>
  iCount := 0;
  lsValue := pStrValue;
  i := pos(pStrToken, lsValue);
  while i  0 do begin
    delete(lsValue, i, length(pStrToken));
    inc(iCount);
    i := pos(pStrToken, lsValue);
  end;
  Result := iCount + 1;
end;
function tiToken(const pStrValue, pStrToken : string; const pIntNum :
integer) : string;
var
  i, iCount, iNumToken : integer;
  lsValue : string;
begin
  result := '';
  iNumToken := tiNumToken(pStrValue, pStrToken);
  if pIntNum = 1 then begin
    if pos(pStrToken, pStrValue) = 0 then result := pStrValue
    else result := copy(pStrValue, 1, pos(pStrToken, pStrValue)-1);
    end
  else if (iNumToken < pIntNum-1) or (pIntNum<1) then begin
    result := '';
    end
  else begin
    { Remove leading blocks }
    iCount := 1;
    lsValue := pStrValue;
    i := pos(pStrToken, lsValue);
    while (i0) and (iCount<pIntNum) do begin
      delete(lsValue, 1, i + length(pStrToken) - 1);
      inc(iCount);
      i := pos(pStrToken, lsValue);
    end;
    if (i=0) and (iCount=pIntNum) then result := lsValue
    else if (i=0) and (iCountpIntNum) then
      result := ''
    else
      result := copy(lsValue, 1, i-1);
  end;
end;

----------------------------------------------

Below is the Unit Tests explaining how it works and expected results

--------------------------------------------
procedure TTestTIUtils.tiNumToken ;
begin
  CheckEquals( 0, tiUtils.tiNumToken( '', ',' ), 'Failed on 1' ) ;
  CheckEquals( 1, tiUtils.tiNumToken( 'adf adf', ',' ), 'Failed on 2' ) ;
  CheckEquals( 2, tiUtils.tiNumToken( 'adf,', ',' ), 'Failed on 3' ) ;
  CheckEquals( 2, tiUtils.tiNumToken( 'adf,adf', ',' ), 'Failed on 4' ) ;
  CheckEquals( 3, tiUtils.tiNumToken( 'adf,adf,adf', ',' ), 'Failed on 5' ) ;
end ;
procedure TTestTIUtils.tiToken ;
begin
  CheckEquals( '', tiUtils.tiToken( '', ',', 1 ), 'Failed on 1' ) ;
  CheckEquals( 'a', tiUtils.tiToken( 'a,b,c', ',', 1 ), 'Failed on 2' ) ;
  CheckEquals( 'b', tiUtils.tiToken( 'a,b,c', ',', 2 ), 'Failed on 3' ) ;
  CheckEquals( 'c', tiUtils.tiToken( 'a,b,c', ',', 3 ), 'Failed on 4' ) ;
  CheckEquals( '', tiUtils.tiToken( 'a,b,c', ',', 4 ), 'Failed on 5' ) ;
  CheckEquals( 'aa', tiUtils.tiToken( 'aa,bb,cc', ',', 1 ), 'Failed on 6' ) ;
  CheckEquals( 'bb', tiUtils.tiToken( 'aa,bb,cc', ',', 2 ), 'Failed on 7' ) ;
  CheckEquals( 'cc', tiUtils.tiToken( 'aa,bb,cc', ',', 3 ), 'Failed on 8' ) ;
  CheckEquals( '', tiUtils.tiToken( 'aa,bb,cc', ',', 4 ), 'Failed on 9' ) ;
end ;

---------------------------------------------

Basically you can do a simple for loop:

for i := 1 to tiNumToken(string, '|') do
   stringvalue :=  tiToken(string, '|', i);
   ....

Regards,
- Graeme -