Загрузка StringGrid из текстового файла - PullRequest
0 голосов
/ 06 февраля 2012

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

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

  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;

Ответы [ 3 ]

1 голос
/ 06 февраля 2012

Лично я бы предпочел не использовать здесь 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 голосов
/ 06 февраля 2012

Попробуйте это

    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;
0 голосов
/ 06 февраля 2012

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

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

...