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 行组成。一行看起来像这样

300: rani : joseph: 210: 500 : 700

如果该行在第 3 位有数字 210,我必须检索存储在数据库中的员工的更多详细信息。我该怎么做?

我想读取文件中的所有行。

谢谢你的时间。

4

2 回答 2

1

不要忘记从 tsl 回收内存,这样它就不会泄漏。

看来您来自某种垃圾收集语言,懒惰的语言,您根本不考虑内存,例如 PHP 或 Python。

因此,您最好阅读有关对象及其生命的 Delphi 帮助,或者阅读一些类似于 Delphi Foundations 的书。

在那之前... 变体 3:由于您似乎没有控制和管理对象生命周期所需的技能,因此请使用引用计数类型,如数组或接口,Delphi 或多或少地控制它们的生命周期。

从将字符串拆分为基于分隔符的字符串数组中的答案进行详细说明,您可以起草一些变体,例如:

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 函数只需要一行代码。

sList.text:=StringReplace(AString,ADelimiter,#13#10,[rfReplaceAll]);
  • 只有4个变量。
  • 只有 1 个 TStringList 。

用德尔福 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 回答