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

前端 未结 2 1090
星月不相逢
星月不相逢 2020-12-20 07:09

Here is my code.

var
  filehan : Textfile;
  i : Integer;
  LineOfText   : String;
  tsl : TStringList;
  Name, Emp_id : string;
begin
  stf := TStringList.c         


        
相关标签:
2条回答
  • 2020-12-20 07:53

    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
    
    0 讨论(0)
  • 2020-12-20 08:03

    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;
    
    0 讨论(0)
提交回复
热议问题