如何将分隔的 TStringlist 解析为整数的动态多维数组?
How to parse delimited TStringlist to dynamic multidimensional array of integer?
我一直在上下搜索 Delphi 函数或任何可以将 space 分隔的 TStringList(从 *.asc 文件加载)解析为动态二维整数数组的信息。
我有一个 ASCII 网格文件,其中包含网格格式的高程。首先,我将文件读入 TStringlist,将 header 数据提取到变量中,然后从 TStringlist 中删除 header 数据。我剩下的是一个 TStringlist,在 3601 x 3601 的网格中只有高程数据,每个值由 space 分隔。由于这个 Stringlist 仍在内存中,我想用海拔数据填充一个二维整数数组,然后释放 TStringList。
根据我的搜索,我偶然发现了一段代码 here 可以工作,但不完全。
我有的是:
var sourceData, tmpGrid, tmpRow : TStringList;
val : String;
Pos, i, j, k, l : Integer;
nCols, nRows, noData : Integer;
xllCorner, yllCorner, cellSize : Extended;
Dem : array of array of Integer;
begin
val := '';
sourceData := TStringList.Create;
tmpGrid := TStringList.Create;
tmpRow := TStringList.Create;
tmpRow.StrictDelimiter := True;
tmpRow.Delimiter := ' ';
sourceData.LoadFromFile('D:\ZA_DEM_DATA\Bulk_Order_466486\ARCASCII\s30_e026_1arc_v3.asc');
nCols := StrToInt(StripNonConforming(sourceData.Strings[0], ['0'..'9', '+', '-', '.']));
nRows := StrToInt(StripNonConforming(sourceData.Strings[1], ['0'..'9', '+', '-', '.']));
xllCorner := StrToFloat(StripNonConforming(sourceData.Strings[2], ['0'..'9', '+', '-', '.']));
yllCorner := StrToFloat(StripNonConforming(sourceData.Strings[3], ['0'..'9', '+', '-', '.']));
cellSize := StrToFloat(StripNonConforming(sourceData.Strings[4], ['0'..'9', '+', '-', '.']));
noData := StrToInt(StripNonConforming(sourceData.Strings[5], ['0'..'9', '+', '-', '.']));
Edit1.Text := IntToStr(nCols);
Edit2.Text := IntToStr(nRows);
Edit3.Text := FloatToStr(xllCorner);
Edit4.Text := FloatToStr(yllCorner);
Edit5.Text := FloatToStr(cellSize);
Edit6.Text := IntToStr(noData);
for I := 0 to 5 do
begin
sourceData.Delete(0);
end;
//This is where I start parsing my TStrinList
tmpGrid.DelimitedText := sourceData.Text;
SetLength(Dem, nCols, nRows);
Edit7.Text := IntToStr(sourceData.Count);
try
for i := 0 to sourceData.Count -1 do
for j := 0 to sourceData.Count -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
end;
finally
sourceData.Free;
end;
StringGrid1.ColCount := nCols;
StringGrid1.RowCount := nRows;
//This is mainly to visualise the data while testing the code
for i := 0 to nCols -1 do
for j := 0 to nRows -1 do
begin
StringGrid1.Cells[i, j] := IntToStr(dem[i, j]);
end;
end;
我得到的结果是原始文件中显示的第一个 "row" 数据,但已复制到数组的所有行。例如:
原始数据:
1. 1245 1268 1232 1258
2. 1354 1321 1578 1689
3. 1461 1423 1475 1427
4. 1598 1541 1562 1550
我得到的是:
1. 1245 1268 1232 1258
2. 1245 1268 1232 1258
3. 1245 1268 1232 1258
4. 1245 1268 1232 1258
我们将不胜感激任何帮助。
这似乎是导致错误结果的原因
for i := 0 to sourceData.Count -1 do
for j := 0 to sourceData.Count -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
end;
您已将实际数据从 SourceData 移动到不需要的 tmpGrid。相反,一次从 SourceData 分配一行到 tmpRow,然后一次从 tmpRow 读取一个值,并分配给值数组:
for i := 0 to SourceData.Count-1 do
begin
tmpRow.DelimitedText := SourceData[i];
for j := 0 to tmpRow.Count-1 do
Dem[i,j] := StrToInt(tmpRow[j]);
end;
就在这行代码之后
//This is where I start parsing my TStrinList
tmpGrid.DelimitedText := sourceData.Text;
您的 sourceData
包含 4 行文本
1245 1268 1232 1258
1354 1321 1578 1689
1461 1423 1475 1427
1598 1541 1562 1550
和tmpGrid
包含16行文本
1245
1268
1232
1258
1354
1321
1578
1689
1461
1423
1475
1427
1598
1541
1562
1550
但您只能访问每行从 0 到 3 的 tmpGrid 行
for i := 0 to sourceData.Count -1 do
for j := 0 to sourceData.Count -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
end;
您应该更改代码以使用 nCols
和 nRows
中的值,然后计算 tmpGrid
中的行
for i := 0 to nCols -1 do
for j := 0 to nRows -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i + j*nCols]);
end;
i = 0 // first column
j = 1 // second row
i + j * nCols => 0 + 4 => fifth line of tmpGrid (zero indexed)
我一直在上下搜索 Delphi 函数或任何可以将 space 分隔的 TStringList(从 *.asc 文件加载)解析为动态二维整数数组的信息。
我有一个 ASCII 网格文件,其中包含网格格式的高程。首先,我将文件读入 TStringlist,将 header 数据提取到变量中,然后从 TStringlist 中删除 header 数据。我剩下的是一个 TStringlist,在 3601 x 3601 的网格中只有高程数据,每个值由 space 分隔。由于这个 Stringlist 仍在内存中,我想用海拔数据填充一个二维整数数组,然后释放 TStringList。
根据我的搜索,我偶然发现了一段代码 here 可以工作,但不完全。
我有的是:
var sourceData, tmpGrid, tmpRow : TStringList;
val : String;
Pos, i, j, k, l : Integer;
nCols, nRows, noData : Integer;
xllCorner, yllCorner, cellSize : Extended;
Dem : array of array of Integer;
begin
val := '';
sourceData := TStringList.Create;
tmpGrid := TStringList.Create;
tmpRow := TStringList.Create;
tmpRow.StrictDelimiter := True;
tmpRow.Delimiter := ' ';
sourceData.LoadFromFile('D:\ZA_DEM_DATA\Bulk_Order_466486\ARCASCII\s30_e026_1arc_v3.asc');
nCols := StrToInt(StripNonConforming(sourceData.Strings[0], ['0'..'9', '+', '-', '.']));
nRows := StrToInt(StripNonConforming(sourceData.Strings[1], ['0'..'9', '+', '-', '.']));
xllCorner := StrToFloat(StripNonConforming(sourceData.Strings[2], ['0'..'9', '+', '-', '.']));
yllCorner := StrToFloat(StripNonConforming(sourceData.Strings[3], ['0'..'9', '+', '-', '.']));
cellSize := StrToFloat(StripNonConforming(sourceData.Strings[4], ['0'..'9', '+', '-', '.']));
noData := StrToInt(StripNonConforming(sourceData.Strings[5], ['0'..'9', '+', '-', '.']));
Edit1.Text := IntToStr(nCols);
Edit2.Text := IntToStr(nRows);
Edit3.Text := FloatToStr(xllCorner);
Edit4.Text := FloatToStr(yllCorner);
Edit5.Text := FloatToStr(cellSize);
Edit6.Text := IntToStr(noData);
for I := 0 to 5 do
begin
sourceData.Delete(0);
end;
//This is where I start parsing my TStrinList
tmpGrid.DelimitedText := sourceData.Text;
SetLength(Dem, nCols, nRows);
Edit7.Text := IntToStr(sourceData.Count);
try
for i := 0 to sourceData.Count -1 do
for j := 0 to sourceData.Count -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
end;
finally
sourceData.Free;
end;
StringGrid1.ColCount := nCols;
StringGrid1.RowCount := nRows;
//This is mainly to visualise the data while testing the code
for i := 0 to nCols -1 do
for j := 0 to nRows -1 do
begin
StringGrid1.Cells[i, j] := IntToStr(dem[i, j]);
end;
end;
我得到的结果是原始文件中显示的第一个 "row" 数据,但已复制到数组的所有行。例如:
原始数据:
1. 1245 1268 1232 1258 2. 1354 1321 1578 1689 3. 1461 1423 1475 1427 4. 1598 1541 1562 1550
我得到的是:
1. 1245 1268 1232 1258 2. 1245 1268 1232 1258 3. 1245 1268 1232 1258 4. 1245 1268 1232 1258
我们将不胜感激任何帮助。
这似乎是导致错误结果的原因
for i := 0 to sourceData.Count -1 do
for j := 0 to sourceData.Count -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
end;
您已将实际数据从 SourceData 移动到不需要的 tmpGrid。相反,一次从 SourceData 分配一行到 tmpRow,然后一次从 tmpRow 读取一个值,并分配给值数组:
for i := 0 to SourceData.Count-1 do
begin
tmpRow.DelimitedText := SourceData[i];
for j := 0 to tmpRow.Count-1 do
Dem[i,j] := StrToInt(tmpRow[j]);
end;
就在这行代码之后
//This is where I start parsing my TStrinList
tmpGrid.DelimitedText := sourceData.Text;
您的 sourceData
包含 4 行文本
1245 1268 1232 1258 1354 1321 1578 1689 1461 1423 1475 1427 1598 1541 1562 1550
和tmpGrid
包含16行文本
1245 1268 1232 1258 1354 1321 1578 1689 1461 1423 1475 1427 1598 1541 1562 1550
但您只能访问每行从 0 到 3 的 tmpGrid 行
for i := 0 to sourceData.Count -1 do
for j := 0 to sourceData.Count -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
end;
您应该更改代码以使用 nCols
和 nRows
中的值,然后计算 tmpGrid
for i := 0 to nCols -1 do
for j := 0 to nRows -1 do
begin
Dem[i][j] := StrToInt(tmpGrid.Strings[i + j*nCols]);
end;
i = 0 // first column j = 1 // second row i + j * nCols => 0 + 4 => fifth line of tmpGrid (zero indexed)