如何在delphi中使用此过程获取两个不同的文件

时间:2012-08-09 06:30:42

标签: delphi parsing matrix delimited-text

我想从两个文件.txt中获取值,一个文件包含与其他文件不同的维度矩阵

我试过这段代码:

  procedure TfrmJST.ParseDelimited(const S1: TStrings; const Value: String; const Delimiter: String);
    var
      dx,cx: integer;
      ns,ms: String;
      txt: string;
      delta,teta: integer;

   procedure TfrmJST.ParseDelimited(const S1: TStrings; const Value: String; const Delimiter: String);
var
  dx,cx: integer;
  ns,ms: String;
  txt: string;
  delta,teta: integer;

    begin
     Col := 1;
     Delta := Length(Delimiter);
     Txt := Value+Delimiter;;
     begin
      while Length(Txt) > 1 do
      begin
        Dx := Pos(Delimiter, Txt);
        Ns := Trim(Copy(Txt, 1, Dx-1));
    //    S1.Add('#'+Ns+'*');             //only needed for testing
        if Ns <> '' then
        begin
          Matrix[Row,Col] := StrToFloat(Ns);    //for first matrix
          Inc(Col);
        end;
        Txt := Copy(Txt, Dx+Delta, MaxInt);
      end;
     end;



     Col := 1;
     teta := Length(delimiter);
     txt := value+delimiter;
     begin
      while Length(txt) > 1 do
      begin
        cx := Pos(delimiter, txt);
        ms := Copy(txt, 1, cx-1);
        if ms <> '' then
          begin
          ref[Row,Col] := StrToFloat(ms);    ///for 2nd matrix

          Inc(Col);
          end;
          txt := Copy(txt, cx+teta, MaxInt);
      end;
     end;
    end;

这是矩阵的初始化:

private
    { Private declarations }
    Row, Col: integer;
    Matrix: array[1..140,1..141] of double;
     Ref: array[1..2,1..140] of double ;

这是实施:

begin
  Temp := TStringList.Create;
  MemoSL:= TStringList.Create ;
  Temp.LoadFromFile('trainer.txt');
  Row := 1;
  for I := 0 to Temp.Count-1 do
  begin
    ParseDelimited(MemoSL, Trim(Temp.Strings[I]), ' ');
    Inc(Row); //stackoverflow error in this line
  end;
  Temp.Free;

 //parsing second matrix
  TempList := TStringList.Create;
  Templist.LoadFromFile('refbaru.txt');
  row := 1;
  for J := 0 to Templist.Count-1 do
  begin
 T := Templist[J];
 ParseDelimited(Memo1.Lines, T, ' ');
  Inc(row);
  end;
  Templist.Free;

我试过那段代码,但是给我错误, 错误是处理第一个矩阵的行'inc(row)'中的stackoverflow错误。 当我在处理第二个矩阵的第二个函数中发表评论时,Temp [i]只返回2行矩阵[140x141]。这是否意味着代码无法处理两个不同的文件?为什么它只返回两行矩阵?  有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:1)

while Length(Txt) > 1 do
begin
  Dx := Pos(Delimiter, Txt);
  Ns := Trim(Copy(Txt, 1, Dx-1));
  //    S1.Add('#'+Ns+'*');             //only needed for testing
  if Ns <> '' then
  begin
    Matrix[Row,Col] := StrToFloat(Ns);    //for first matrix
    Inc(Col);
  end;
  Txt := Copy(Txt, Dx+Delta, MaxInt);
end;

看看这段代码,我看到无限循环的可能性:如果找不到分隔符会发生什么?它将继续运行并永远增加你的'col'值。如果没有找到分隔符,请确保有条件停止while循环。

答案 1 :(得分:1)

当许多普通错误已经存在时,寻找特定的堆栈溢出错误是没有意义的。

如果您的代码编程干净且仍然是stack overflow,那么当然是时候深入了解代码了。
但首先 !只要您能看到明显的错误,就应该删除它们。

  • 1。)“行”在140维数组和仅2维数组上的相同过程中使用。 这怎么可行?

矩阵:double的数组[1..140,1..141];
参考:double的数组[1..2,1..140];
文件'trainer.txt'140行
文件'refbaru.txt'2行。

for I := 0 to Temp.Count-1 do // 140 lines
// ParseDelimited() will only run properly if Row < 3 
// remember -> Ref: array[1..2,1..140])
// if Row > 2 , with Ref[Row,Col] := , 137 times data is overwritten.

   procedure ParseDelimited(MemoSL, Trim(Temp.Strings[I]), ' ');
      ....
      Matrix[Row,Col] := StrToFloat(Ns);
      ....
      Ref[Row,Col] := StrToFloat(ms); 
      ....
   end;
Inc(Row);
end;
  • 2。)如果您使用loop运行第二个refbaru.txt,并且在ParseDelimited()过程中两个数组一起出现,那么您将覆盖数组Matrix的2个值

推荐

  • 确保:循环显示trainer.txt,仅将值写入Matrix array
  • 确保:循环显示refbaru.txt,仅将值写入Ref array

您的代码可能类似于:

[...]
filetoload: String;
[...]
procedure TfrmJST.ParseDelimited(S1: TStrings; Value: String; const Delimiter: String);
var
 f:double;
[...]
     Col := 1;
     txt := Value+Delimiter;
[...]
if filetoload='trainer.txt' then begin
     Delta := Length(Delimiter);
      while Length(txt) > 1 do
      begin
        Dx := Pos(Delimiter, txt);
        Ns := Trim(Copy(txt, 1, Dx-1));
        if Ns <> '' then
        begin
          if TryStrToFloat(Ns,f) then Matrix[Row,Col]:=f;
          Inc(Col);
          if Col > MatrixColMax then break;
          txt := Copy(txt, Dx+Delta, MaxInt);        
        end else txt:='';
      end;
end;

if filetoload='refbaru.txt' then begin
     teta := Length(delimiter);
      while Length(txt) > 1 do
      begin
        cx := Pos(delimiter, txt);
        ms := Copy(txt, 1, cx-1);
        if ms <> '' then
          begin
          if TryStrToFloat(ms,f) then Ref[Row,Col]:=f;
          Inc(Col);
          if Col > RefColMax then break;
          txt := Copy(txt, cx+teta, MaxInt);
          end else txt:='';
      end;
end;

begin
[...]

filetoload:='trainer.txt';
Temp := TStringList.Create;
Temp.LoadFromFile(filetoload);
if Temp.Count > MatrixRowMax then LinesToLoad:=MatrixRowMax-1 else
                                  LinesToLoad:=Temp.Count-1;
for I := 0 to LinesToLoad do
   [...]
   ParseDelimited(MemoSL, Trim(Temp.Strings[I]), ' ');
   [...]
end;

filetoload:='refbaru.txt';
TempList := TStringList.Create;
TempList.LoadFromFile(filetoload);
if TempList.Count > RefRowMax then LinesToLoad:=RefRowMax-1 else 
                                   LinesToLoad:=TempList.Count-1;
for J := 0 to LinesToLoad do
   [...]
   ParseDelimited(Memo1.Lines, T, ' ');
   [...]
end;
end;

您还应该将文件的线条大小与数组的大小进行比较

RefRowMax: integer;
RefColMax: integer;
MatrixRowMax: integer;
MatrixColMax: integer;
LinesToLoad: integer;

....

RefRowMax:=2;
RefColMax:=140;
MatrixRowMax:=140;
MatrixColMax:=141;
....

程序ParseDelimited()

if filetoload='trainer.txt' then begin
 [...]
 Inc(Col)
 if Col > MatrixColMax then break;

end;

if filetoload='refbaru.txt' then begin
 [...]
 Inc(Col)
 if Col > RefColMax then break;

end;

在写入ParseDelimited()中的数组之前,您还应该查找有效值NsStrToFloat(Ns)

  • function TryStrToFloat(const S:string; out Value:Double):Boolean;
  • 缬氨酸();

  var
  f:double;
  ....
  begin
  ....
  if TryStrToFloat(Ns,f) then Matrix[Row,Col]:=f;
  ....

OP覆盖了许多已使用的数据 当他有足够的数据被覆盖时,他会收到堆栈溢出错误。

enter image description here

enter image description here

enter image description here