如何将分隔的TStringlist解析为动态多维数组的整数?

时间:2015-04-02 11:15:43

标签: arrays delphi parsing delphi-xe7 tstringlist

我一直在搜索Delphi函数的高低,或者任何可以将空格分隔的TStringList(从* .asc文件加载)解析为整数的动态2D数组的信息。

我所拥有的是具有网格格式高程的ASCII网格文件。首先,我将文件读入TStringlist,在那里我将头数据提取到变量,然后从TStringlist中删除头数据。我剩下的是一个TStringlist,只有3601 x 3601网格中的高程数据,每个值用空格分隔。由于此Stringlist仍在内存中,我想用高程数据填充整数的2D数组,然后释放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;

我得到的结果是第一个"行"数据显示在原始文件中,但复制到数组的所有行。例如:

原始数据:

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

非常感谢任何和所有帮助。

2 个答案:

答案 0 :(得分:2)

这似乎是错误结果的原因

 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;

答案 1 :(得分:2)

在此代码行之后

//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;

您应该更改代码以使用nColsnRows中的值,然后计算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)