• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 682
  • Last Modified:

TStrings and FormatStr searching

Hi Experts,


I have a TStrings with the following data

Header=Status
Key=S%.2d
S01=AAAA
S02=BBBB
S03=CCC
S04=DDDD
Date=1/3/05

(thats right it is read in straight in from an inifile)

I can easily extract the Key feild, what I then want do if any String matches the Key (FormatSTR) I will keep else I will delete it from the colection (including the string containing the Key ('Key=S%.2d'). They way I started to write is long winded an inefficient. Does anyone know of a "Simple" routine of doing this.

Cheers

gtwod


0
GTwoD
Asked:
GTwoD
  • 3
  • 2
  • 2
  • +1
3 Solutions
 
pritaeasSoftware EngineerCommented:
I could be easier for you to use regular expressions to perform this task. There are a lot of samples using regexp already discussed here on XX - Delphi.

hth, pritaeas
0
 
mikelittlewoodCommented:
If you loaded the strings into a TStringList, you could loop through and just do a compare on every line, delete what you dont need

for iloop := Pred(StringList1.Count) downto 0 do
  if StringList1[iloop] <> FormatStr() then
    StringList1.delete(iLoop);
0
 
pritaeasSoftware EngineerCommented:
Yes, but how would you check the current line with the format string. In the given example it can be anything from S00 thru S99, and I think his problem will be, that the given string can be a lot more difficult...
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
mikelittlewoodCommented:
Maybe he needs to be a bit more clear what results he wants then.

Could you post a before and after TStrings set so we can see what you want as the result please.

Maybe in my code above he needs to alter it to
  if Pos(FormatStr(), StringList1[iLoop]) > 0 then

<what I then want do if any String matches the Key (FormatSTR) I will keep else I will delete it >
When you say if any string matches the key, do you really mean if the key is the first part of the string (i.e. Key := S01), then delete ALL lines except S01=AAAA?
0
 
GTwoDAuthor Commented:
Sorry, if it is a bit wooly

in Snn, you cannot assume that nn corresponds to the String pos in TStrings,


I have 2 worked examples....

Example 1

Before...

Check=ISDNStatus.ini Found & Opened
Key=S%.2d
Fields=TextColor,SColorRed,SColorGreen,SColorBlue,Description,Init,
S00=w,000,000,000,Unknown,Unk,
S01=w,196,196,196,Not Installed,NtI,
S02=b,255,128,255,Fault,Fault,
S03=b,214,214,214,Idle,Idl,
S04=b,255,128,064,Proceeding,Prc,
S05=b,255,128,064,Ringing,Rng,
S06=b,255,064,064,Connected,Con,
S07=b,064,255,064,Framed,Frd,
//S08=w,096,114,128,Grabbed,Grb,
S45=w,23,56,89,madeup,mum,

After...

S00=w,000,000,000,Unknown,Unk,
S01=w,196,196,196,Not Installed,NtI,
S02=b,255,128,255,Fault,Fault,
S03=b,214,214,214,Idle,Idl,
S04=b,255,128,064,Proceeding,Prc,
S05=b,255,128,064,Ringing,Rng,
S06=b,255,064,064,Connected,Con,
S07=b,064,255,064,Framed,Frd,
S45=w,23,56,89,madeup,mum,

Example 2

Check=ISDNCodecs.ini Found & Opened
Key=C%.3d
Fields=Type,ComPort,Baud,Bits,Parity,Num1,Num2,Num3,Num4,Num5,Num6,Init String,MiscName,
Prefix=C
C000=CT01,3,9600,8,N,20838201,,,,,,,,,
C001=CT01,4,9600,8,N,20838202,,,,,,,,,
C002=CT01,5,9600,8,N,20838203,,,,,,,,,
C003=CT01,6,9600,8,N,20838204,,,,,,,,,
C004=CT01,7,9600,8,N,20838205,,,,,,,,,
C005=CT01,8,9600,8,N,20838206,,,,,,,,,
C006=CT01,9,9600,8,N,20838207,,,,,,,,,
C007=CT01,10,9600,8,N,20838208,,,,,,,,,
C008=CT01,11,9600,8,N,20838209,,,,,,,,,
C009=CT01,12,9600,8,N,20838210,,,,,,,,,
C010=CT01, 13,9600,8,N,20838211,,,,,,,,,
C011=CT01, 14,9600,8,N,20838212,,,,,,,,,
C012=CT01, 15,9600,8,N,20838213,,,,,,,,,
C013=CT01, 16,9600,8,N,20838214,,,,,,,,,
C014=CT01, 17,9600,8,N,20838215,,,,,,,,,
C015=CT01, 18,9600,8,N,20838216,,,,,,,,,
C016=CT01, 19,9600,8,N,20838217,,,,,,,,,
C017=CT01, 20,9600,8,N,20838218,,,,,,,,,
C020=CT01, 23,9600,8,N,20581521,,,,,,,,,
C021=CT01, 24,9600,8,N,20581522,,,,,,,,,
C022=CT01, 25,9600,8,N,20581523,,,,,,,,
C023=CT01, 26,9600,8,N,20581524,,,,,,,,
C025=CT01, 28,9600,8,N,20581526,,,,,,,,
C026=CT01, 29,9600,8,N,20581527,,,,,,,,,
C027=CT01, 30,9600,8,N,20581528,,,,,,,,,
//C030=CT01,,,,,,,,,,,,
//C031=CT01,,,,,,,,,,,,
C032=CT01, 38,9600,8,N,20581501,,,,,,,OutGoing 1,
C033=CT01, 39,9600,8,N,20581502,,,,,,,OutGoing 2,
C034=CT01, 40,9600,8,N,20581503,,,,,,,OutGoing 3,
C035=CT01, 41,9600,8,N,20581

After

C000=CT01,3,9600,8,N,20838201,,,,,,,,,
C001=CT01,4,9600,8,N,20838202,,,,,,,,,
C002=CT01,5,9600,8,N,20838203,,,,,,,,,
C003=CT01,6,9600,8,N,20838204,,,,,,,,,
C004=CT01,7,9600,8,N,20838205,,,,,,,,,
C005=CT01,8,9600,8,N,20838206,,,,,,,,,
C006=CT01,9,9600,8,N,20838207,,,,,,,,,
C007=CT01,10,9600,8,N,20838208,,,,,,,,,
C008=CT01,11,9600,8,N,20838209,,,,,,,,,
C009=CT01,12,9600,8,N,20838210,,,,,,,,,
C010=CT01, 13,9600,8,N,20838211,,,,,,,,,
C011=CT01, 14,9600,8,N,20838212,,,,,,,,,
C012=CT01, 15,9600,8,N,20838213,,,,,,,,,
C013=CT01, 16,9600,8,N,20838214,,,,,,,,,
C014=CT01, 17,9600,8,N,20838215,,,,,,,,,
C015=CT01, 18,9600,8,N,20838216,,,,,,,,,
C016=CT01, 19,9600,8,N,20838217,,,,,,,,,
C017=CT01, 20,9600,8,N,20838218,,,,,,,,,
C020=CT01, 23,9600,8,N,20581521,,,,,,,,,
C021=CT01, 24,9600,8,N,20581522,,,,,,,,,
C022=CT01, 25,9600,8,N,20581523,,,,,,,,
C023=CT01, 26,9600,8,N,20581524,,,,,,,,
C025=CT01, 28,9600,8,N,20581526,,,,,,,,
C026=CT01, 29,9600,8,N,20581527,,,,,,,,,
C027=CT01, 30,9600,8,N,20581528,,,,,,,,,
C032=CT01, 38,9600,8,N,20581501,,,,,,,OutGoing 1,
C033=CT01, 39,9600,8,N,20581502,,,,,,,OutGoing 2,
C034=CT01, 40,9600,8,N,20581503,,,,,,,OutGoing 3,
C035=CT01, 41,9600,8,N,20581

This is what I have wrote so far...


  swapStr:=Key;//'S%.2D' or 'C%.3D'
  Delete(swapStr,1,3);
  Delete(swapStr,length(swapStr),1);
  //ShowMessage(swapStr);
  w:=StrToInt(swapStr);

  for i:=0 to StatusSettings.Count-1 do
  begin
    valid:=false;

    if pos(StatusID[1],StatusSettings.Strings[i])=1 then
    begin
      if Numeric(copy(StatusSettings.Strings[i],2,w),w) then
      begin
        valid:=true;
      end
    end;

    if valid then
    begin
      swapchar(StatusSettings.Strings[i],'=',',');

    end
     else
    begin
      StatusSettings.Strings[i]:='';
    end;
  end;
 
  //then loop around and delete the null strings.

  ShowMessage(StatusSettings.GetText);

This works ....howeverI think the code is very inefficient is there a better way.

0
 
GTwoDAuthor Commented:
Sorry

 if pos(StatusID[1],StatusSettings.Strings[i])=1 then

should be

 if pos(key,StatusSettings.Strings[i])=1 then


and numeric(string,len) is a function returns true if all the if string is len in length and all charecters are between 0-9

0
 
mikelittlewoodCommented:
Check=ISDNStatus.ini Found & Opened
Key=S%.2d
Fields=TextColor,SColorRed,SColorGreen,SColorBlue,Description,Init,
S00=w,000,000,000,Unknown,Unk,
S01=w,196,196,196,Not Installed,NtI,
S02=b,255,128,255,Fault,Fault,
S03=b,214,214,214,Idle,Idl,
S04=b,255,128,064,Proceeding,Prc,
S05=b,255,128,064,Ringing,Rng,
S06=b,255,064,064,Connected,Con,
S07=b,064,255,064,Framed,Frd,
//S08=w,096,114,128,Grabbed,Grb,
S45=w,23,56,89,madeup,mum,

After...

S00=w,000,000,000,Unknown,Unk,
S01=w,196,196,196,Not Installed,NtI,
S02=b,255,128,255,Fault,Fault,
S03=b,214,214,214,Idle,Idl,
S04=b,255,128,064,Proceeding,Prc,
S05=b,255,128,064,Ringing,Rng,
S06=b,255,064,064,Connected,Con,
S07=b,064,255,064,Framed,Frd,
S45=w,23,56,89,madeup,mum,

so if Key=S08, you want to delete the line containing S08 and also delete any lines before the first key to compare against

var
  KeyPrefix: String;
  KeyLen: Integer;
begin
  // Ill let you set what the value should be
  //Key := Format();
  Key := 'S08';
  KeyPrefix := Copy(Key, 1, 1);
  KeyLen := Length(Key);
  // assuming using a stringlist
  for i:= Pred(StatusSettings.Count) downto 0 do
  begin
    // check if its a key line
    if (Copy(StatusSettings.Strings[i], 1, 1) = KeyPrefix) and
       (Length(Copy(StatusSettings.Strings[i], 1, Pos('=', StatusSettings.Strings[i])-1)) = KeyLen) then
    begin
      // check if the key exists in the string to delete
      if Copy(StatusSettings.Strings[i], 1,KeyLen) = Key then
        StatusSettings.Delete(i);
    end
    // else just get rid of the line
    else
      StatusSettings.Delete(i);
  end;

Bit of a guess as Im not on a PC using Delphi at the moment.
Im assuming the length of the key string will not vary once it gets set in my bit of code
0
 
Slick812Commented:
you might try something like

for i := StatusSettings.Count-1 DownTo 0 do
  begin
  if (StatusSettings[i][1] <> StatusID[1]) or not (StatusSettings[i][2] in ['0'..'9']) then
    sList1.Delete(i);
  end;

untested, just from head
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now