1

これが私のコードです。

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;

ファイルは約 2000 行で構成されています。1行は次のようになります

300: rani : joseph: 210: 500 : 700

行の 3 番目の位置に 210 という番号がある場合、データベースに保存されている従業員の詳細を取得する必要があります。どうすればそれができますか?

ファイル内のすべての行を読み取りたい。

御時間ありがとうございます。

4

2 に答える 2

1

メモリがリークしないように、tsl からメモリを再利用することを忘れないでください。

あなたは、PHP や Python のように、メモリについてまったく考えていない、ガベージコレクションされた言語、怠惰な言語から来たようです。

したがって、オブジェクトとそのライフについての Delphi ヘルプを読むか、Delphi Foundations のような本を読んだほうがよいでしょう。

それまでは... バリアント 3: オブジェクトの有効期間を制御および管理するために必要なスキルを持っていないようなので、Delphi が多かれ少なかれ有効期間を制御する、配列やインターフェイスなどの参照カウント型を使用します。

Split a string into an array of strings based on a delimiterの回答から詳しく説明すると、次のようないくつかのバリアントを作成できます。

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;

わかりました-あなたは古いDelphi 7を持っていると言ったので、そこにはSplitString関数がありません. しかし、数分時間を割いて作ることができます。http://pastebin.ca/2309695

http://jcl.sf.netから便利な Jedi CodeLib ライブラリを入手することもできます。

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;   

サンプル300: rani : joseph: 210: 500 : 700では、​​実際のデータの周りに多くのスペースがあるようです。次に、それらのスペースを削除する必要があります。好きWriteLN (filehan2, Trim( sda[0] ));か好きか機能isl1.Clear.Add( [ Trim( isl2[0] ),..... に関するマニュアルを読んでください。Trim


回線番号が 210 の場合

次に、「if」ステートメントだけで確認します。

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
于 2013-02-01T15:42:20.393 に答える
0

もっとエレガントなバリエーションがあることは知っていますが、これらはシンプルで理解しやすいものでなければなりません。

混乱しないように変数を試してください

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

一方filehanと他方filehandFFile

TStringList の特定の特性である SubStrings 関数に必要なコードは 1 行だけです。

sList.text:=StringReplace(AString,ADelimiter,#13#10,[rfReplaceAll]);
  • 4つの変数のみ。
  • 1 つの TStringList のみ。

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;

アップデート:

質問を理解したので、210フィールド値のある行にのみ興味があります。新しいファイルのすべての行が必要な場合は、.

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;

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]);

sList[3] のサイズまたは値に基づく:

  • に書き込まれるフィールドを自分で定義できますFSTRING.txt

更新 2:

どのように私はそれを行うだろう.

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;
于 2013-02-01T23:05:46.293 に答える