我想从两个文件.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]。这是否意味着代码无法处理两个不同的文件?为什么它只返回两行矩阵? 有人可以帮帮我吗?
答案 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
,那么当然是时候深入了解代码了。
但首先 !只要您能看到明显的错误,就应该删除它们。
矩阵: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;
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()中的数组之前,您还应该查找有效值Ns
,StrToFloat(Ns)
var
f:double;
....
begin
....
if TryStrToFloat(Ns,f) then Matrix[Row,Col]:=f;
....
OP
覆盖了许多已使用的数据
当他有足够的数据被覆盖时,他会收到堆栈溢出错误。