0

2 つのファイル .txt から値を取得したいのですが、1 つのファイルには別の次元の行列が含まれています。

私はこのコードを試しました:

  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エラーでした。2番目の行列を処理する2番目の関数でコメントアウトしましたが、Temp [i]は2行の行列[140x141]しか返しません。コードが2つの異なるファイルを処理できないということですか? そして、なぜマトリックスの2行しか返さないのですか? 誰でも私を助けることができますか?

4

2 に答える 2

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.)2番目の配列を実行し、loop2refbaru.txtつの配列がプロシージャParseDelimited()に一緒に存在する場合、配列の2つの値を上書きしますMatrix

おすすめ

  • 確認してください:ループスルーし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()で配列に書き込む前にNs、有効な値を探す必要があります。StrToFloat(Ns)

  • function TryStrToFloat(const S:string; out Value:Double):ブール値;
    また
  • Val();

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

使用済みデータのOP多くを上書きします。
そして、十分なデータが上書きされると、スタックオーバーフローエラーが発生します。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

ここに画像の説明を入力してください

于 2012-08-09T16:46:36.503 に答える
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;

このコードを見ると、無限ループの可能性があることがわかります。Delimiter が見つからない場合はどうなるでしょうか。それは実行を続け、「col」値を永遠に増やします。区切り文字が見つからない場合は while ループを停止する条件があることを確認してください。

于 2012-08-09T07:27:53.190 に答える