2012-02-05 3 views
0

Как загрузить текстовый файл с целыми числами, разделенными пробелом, на StringGrid? Каждое число в каждую ячейку. Сетка должна быть прямоугольником, поэтому, если ее не хватает, она должна быть заполнена 0.Загрузка StringGrid из текстового файла

Вот что я сделал до сих пор, но он должен уже установить количество строк и столбцов.

while not eof(f) do 
    begin 
    while not eoln(f) do 
    begin 
     read(f, data); 
     StringGrid1.Cells[p, l] := data; 
     inc(p); 
    end; 
    p := 0; 
    readln(f); 
    inc(l); 
    end; 
+5

Почему вы используете Pascal IO? Почему бы вам просто не загрузить файл в список строк и использовать функцию ['SplitString'] (http://docwiki.embarcadero.com/VCL/en/StrUtils.SplitString) для разделения каждой строки? –

+1

Игнорировать ** NO PASCAL I/O ** банда, это нормально для этой задачи. Ваша проблема не является последовательной, как бы вы определяете позиции, если отсутствует несколько последовательных номеров? – OnTheFly

+3

@ user539484 Чистый яд и злоба. Не классный. –

ответ

0

Я бы предлагаю, чтобы попробовать этот код.
Это базовый, но я уверен, что вы можете решить свою проблему.

procedure LoadFile(FileName: string; StringGrid: TStringGrid); 
var 
    temp, fName, sName, eMail: string; 
    sgItem: TStringList; 
    f: textfile; 
begin 
    assignfile(f, FileName); 
    reset(f); 
    sgItem := TStringList.Create; 
    StringGrid.RowCount := 2; 
    while not eof(f) do 
    begin 
    readln(f, temp); 
    fName := copy(temp, 1, pos('|', temp) - 1); 
    delete(temp, 1, pos('|', temp)); 
    sName := copy(temp, 1, pos('|', temp) - 1); 
    delete(temp, 1, pos('|', temp)); 
    eMail := temp; 
    sgItem.Clear; 
    sgItem.Add(fName); 
    sgItem.Add(sName); 
    sgItem.Add(eMail); 
    StringGrid.Rows[StringGrid.RowCount - 1].AddStrings(sgItem); 
    StringGrid.RowCount := StringGrid.RowCount + 1; 
    end; 
    sgItem.Free; 
    closefile(f); 
end; 

Использование:

LoadFile('File.txt', StringGrid1); 

Beny

1

лично я бы избирают не использовать Pascal IO здесь. Если вы хотите, чтобы ваш код мог читать данные Unicode, Pascal IO не может вам помочь.

Вы можете сделать то, что вы описали, используя строковый список для загрузки файла, а затем SplitString из блока StrUtils для синтаксического анализа строки.

procedure PopulateStringGrid(Grid: TStringGrid; const FileName: string); 
var 
    Strings: TStringList; 
    Row, Col: Integer; 
    Items: TStringDynArray; 
begin 
    Grid.RowCount := 0;//clear any previous data 
    Strings := TStringList.Create; 
    try 
    Strings.LoadFromFile(FileName); 
    Grid.RowCount := Strings.Count; 
    for Row := 0 to Strings.Count-1 do 
    begin 
     Items := SplitString(Strings[Row], ' '); 
     for Col := 0 to Grid.ColCount-1 do 
     if Col<Length(Items) then 
      Grid.Cells[Col, Row] := Items[Col] 
     else 
      Grid.Cells[Col, Row] := '0'; 
    end; 
    finally 
    Strings.Free; 
    end; 
end; 

Обратите внимание, что SplitString не может быть именно то, что вам нужно. Например, он не объединяет повторяющиеся разделители в один. Для того, чтобы увидеть, что я имею в виду рассмотреть следующий вход:

Hello World 

Есть 4 пробела между двумя словами и SplitString будет возвращен следующий массив:

'Hello' 
'' 
'' 
'' 
'World' 

Если вы хотите, чтобы рассматривать последовательные разделители как только один разделитель, то вы можете использовать DelimitedText свойство списка строк:

procedure PopulateStringGrid(Grid: TStringGrid; const FileName: string); 
var 
    TextFile, Line: TStringList; 
    Row: Integer; 
begin 
    Grid.RowCount := 0;//clear any previous data 
    TextFile := TStringList.Create; 
    try 
    Line := TStringList.Create; 
    try 
     Line.Delimiter := ' '; 
     TextFile.LoadFromFile(FileName); 
     Grid.RowCount := TextFile.Count; 
     for Row := 0 to TextFile.Count-1 do 
     begin 
     Line.DelimitedText := TextFile[Row]; 
     for Col := 0 to Grid.ColCount-1 do 
      if Col<Line.Count then 
      Grid.Cells[Col, Row] := Line[Col] 
      else 
      Grid.Cells[Col, Row] := '0'; 
     end; 
    finally 
     Line.Free; 
    end; 
    finally 
    TextFile.Free; 
    end; 
end; 
0

Попробуйте

procedure FillStringgrid; 
     // Split the line of text into individual entries 
     procedure Split(const Delimiter: Char;Input: string;const Strings:TStrings); 
     begin 
      Assert(Assigned(Strings)) ; 
      Strings.Clear; 
      Strings.Delimiter := Delimiter; 
      Strings.DelimitedText := Input; 
     end; 
    var 
     strlst : Tstringlist; 
     myfile : TextFile; 
     search : string; 
     i,j  : integer; 
    begin 
     i:= 0; 
     AssignFile(myfile,'filepath'); // specify your file path here 
     Reset(myFile); 
     while not eof(myfile) do 
     begin 
      Readln(myfile,search); 
      strlst:= Tstringlist.Create; 
      Split(' ',search,strlst); // get the no's separated by the delimiter 
      //adjust your column count based on no of entries 
      if StringGrid1.ColCount < strlst.Count then 
      StringGrid1.ColCount := strlst.Count; 
      StringGrid1.Rows[i]:=strlst; // adjust the row count 
      Inc(i); 
      StringGrid1.RowCount := i; 
     end; 
     // free stringlist and textfile  
     CloseFile(myfile) ; 
     strlst .free; 

     // fill in the blank entries with 0 
     for i := 0 to StringGrid1.RowCount - 1 do 
     begin 
     for j := 0 to StringGrid1.ColCount - 1 do 
      begin 
      if StringGrid1.Cells[j,i]='' then 
      StringGrid1.Cells[j,i]:='0'; 
      end; 
     end; 
    end;