简体   繁体   中英

How to save only a particular item in the tstringlist to a file

Here is my code.

var
  filehan : Textfile;
  i : Integer;
  LineOfText   : String;
  tsl : TStringList;
  Name, Emp_id : string;
begin
  stf := TStringList.create;
  Assignfile ( filehan, 'EMP.txt');
  Reset ( filehand );
  While not EOF(filehan) do
  begin
    inc(i);
    ReadLn  ( filehan, LineOfText );
    tsl :=substrings(LineOfText, ':' );
    Name := tsl[1];
    Emp_id := tsl[0];

    tsl.SaveToFile('FSTRING.txt');
  end;

  CloseFile (FFile);
end;

function SubStrings(AString: String; ADelimiter: Char): TStringList;
var
  sList       : TStringList;
  curPos      : Integer;
  subString   : String;
  { DelimiterPos : Integer}
begin
  curPos := 1;
  sList := TStringList.Create;
  while (curPos <= Length(AString)) do 
  begin
    subString := '';
    While (AString[curPos] <> ADelimiter) and
          (curPos <= Length(AString)) do 
    begin
      subString := subString + Copy(AString,curPos,1);
      curPos := curPos + 1;
    end;
    sList.Add(subString);
    curPos := curPos + 1;
  end;
  Result := sList;
end;

The file consist of around 2000 lines. one line looks like this

300: rani : joseph: 210: 500 : 700

If the line has the number 210 at 3rd position,I have to retrieve more details of the employee which is stored in database. How I can do it?

I want to read all the lines in the file.

Thanks for your time.

Don't forget to reclaim the memory from tsl so it won't leak.

It seems you're came from some garbage-collected language, lazy oen where u do not think about memory at all, like PHP or Python.

So you'd better read Delphi help about objects and their life, or read some book liek Delphi Foundations.

Until that... Variant 3: Since you seems not having the required skill to control and manage lifetime of objects, then use reference-counted types, like arrays or interfaces, for which Delphi controls their lifetime more or less.

Elaborating from the answers from Split a string into an array of strings based on a delimiter you can draft few variants, for example:

var sda: TStringDynArray; 
begin
  sda := SplitString(LineOfText, ':' );
  Assignfile ( filehan2, 'FSTRING.txt');
  Rewrite ( filehand2 );
  try
    WriteLN (filehan2, sda[0]);   WriteLN (filehan2, sda[1]);
  finally
    CloseFile(filehan2);
  end;
end;

Okay - since you told you have old Delphi 7 - you do not have SplitString function there. But you can spare few minutes and make one. http://pastebin.ca/2309695

You also can get helpful Jedi CodeLib library from http://jcl.sf.net

var isl1, isl2: IJclStringList;
begin
  isl1 := TJclStringList.Create;
     isl1.LoadFromFile('EMP.txt');
  isl2 := TJclStringList.Create.Split(isl1[0], ':');
  isl1.Clear.Add( [ isl2[0], isl2[1] ] ).SaveToFile('FSTRING.txt');
end;   

With the sample like 300: rani : joseph: 210: 500 : 700 it seems you have a lot of spaces around real data. Then you should trim those spaces off. Like WriteLN (filehan2, Trim( sda[0] )); or like isl1.Clear.Add( [ Trim( isl2[0] ),..... Read manuals about Trim function;


If the line has the number 210

Then check it, just with "if" statement;

var isl1, isl2, isl3: IJclStringList; 
    EveryLine: string; i: integer;
begin
  isl1 := TJclStringList.Create;
  isl2 := TJclStringList.Create;
  isl3 := TJclStringList.Create;

  isl1.LoadFromFile('EMP.txt');

// for EveryLine in isl1 do begin 
//    - this works in free Lazarus or modern Delphi, but not in D7 }
  for i := 0 to isl1.Count - 1 do begin;
      EveryString := isl1[i];

      isl2.Split(EveryString, ':').Trim;
      if isl2.Count >= 4 then // does 3rd element even exist ???
         if StrToIntDef( isl2[3], -1 ) = 210 then
            CallSomeProcedureToRetrieveMoreDetails; 
      isl3.Clear.Add( [ isl2[0], isl2[1] ] ).SaveToFile('FSTRING.txt');
  end; // for
end;  // function

I know there are more elegant variations but these should be simple and understandable.

try your variables is not not to be confused

  Assignfile ( filehan, 'EMP.txt');
  Reset ( filehand );
  CloseFile (FFile);

One filehan and the other filehand and FFile

The particular characteristics of a TStringList, your SubStrings function needs only one line of code.

sList.text:=StringReplace(AString,ADelimiter,#13#10,[rfReplaceAll]);
  • only 4 variables.
  • only 1 TStringList .

Tested with Delphi 5

var
  LineOfText   : String;
  sList : TStringList;
  filehand,Outfilehand: text;

function SubStrings(AString: String; ADelimiter: Char; var sList: TStringList):Boolean;
begin
  sList.text:=StringReplace(AString,ADelimiter,#13#10,[rfReplaceAll]);
end;

begin
  sList := TStringList.Create;
  Assignfile ( filehand, 'EMP.txt');
  Assignfile ( Outfilehand, 'FSTRING.txt');
  Reset ( filehand );
  Rewrite(Outfilehand);
  try
  While not EOF(filehand) do
  begin
    ReadLn  ( filehand, LineOfText );
    LineOfText:=StringReplace(LineOfText,': ',':',[rfReplaceAll]);
    LineOfText:=StringReplace(LineOfText,' :',':',[rfReplaceAll]);
    if pos(':210:',LineOfText)>0 then begin
       substrings(LineOfText, ':' ,sList);
        if (sList.Count=6) then
           if (sList[3]='210') then writeln(Outfilehand,sList[0]+';'+sList[1]);
    end;
  end;
  finally
  sList.Free;
  CloseFile (filehand);
  CloseFile (Outfilehand);
  end;

UPDATE:

I understood the question so that you are only in the row with 210 field value are interested. If you want all the lines in the new file, replace .

if pos(':210:',LineOfText)>0 then begin
        substrings(LineOfText, ':' ,sList);
            if (sList.Count=6) then
               if (sList[3]='210') then writeln(Outfilehand,sList[0]+';'+sList[1]);
end;

with

substrings(LineOfText, ':' ,sList);
   if (sList.Count=6) then
         if (sList[3]='210') then 
         writeln(Outfilehand,sList[0]+';'+sList[1]+';'+sList[4]+';'+sList[5]);
   if (sList.Count=3) then
         writeln(Outfilehand,sList[0]+';'+sList[1]);

Based on the size or value of sList[3] :

  • You can self define which fields are written to FSTRING.txt .

UPDATE2:

How I would do it.

var
  ParsedText   : String;
  inList,outList,sList : TStringList;
  i:integer;

function SubStrings(lineText: String; var sList: TStringList):String;
begin
  result:='ERROR';
  lineText:=StringReplace(lineText,': ',':',[rfReplaceAll]);
  lineText:=StringReplace(lineText,' :',':',[rfReplaceAll]);
  sList.text:=StringReplace(lineText,':',#13#10,[rfReplaceAll]);
    if (sList.Count=6)    then
      if (sList[3]='210') then result:=sList[0]+';'+sList[1]+';'+sList[4]+';'+sList[5] else
                               result:=sList[0]+';'+sList[1];
    if (sList.Count=3)    then result:=sList[0]+';'+sList[1];
end;

begin
  inList  := TStringList.Create;
  outList := TStringList.Create;
  sList   := TStringList.Create;
  try
  inList.LoadFromFile('EMP.txt');
    for i:= 0 to inList.Count-1 do begin
     ParsedText := SubStrings(inList[i],sList);
     if ParsedText <> 'ERROR' then outList.Add(ParsedText);
    end;
  outList.SaveToFile('FSTRING.txt');
  finally
  inList.Free;
  outList.Free;
  sList.Free;
  end;
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM