How can I load text file with integer numbers separated with space to StringGrid? Each number to each cell. Grid has to be a rectangle, so if some number is missing it should be filled with 0.
Here's what I did so far, but it need to have already set row and column count.
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;
CodePudding user response:
I personally would elect not to use Pascal IO here. If you want your code to be able to read Unicode data then Pascal IO cannot help you.
You can do what you describe using a string list to load the file and then SplitString
from the StrUtils
unit to parse the string.
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;
Note that SplitString
may not be precisely what you need. For example it does not coalesce repeated delimiters into one. To see what I mean consider the following input:
Hello World
There are 4 spaces between the two words and SplitString
would return the following array:
'Hello'
''
''
''
'World'
If you wish to treat consecutive delimiters as being just one delimiter then you can use the DelimitedText
property of a string list:
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;
CodePudding user response:
I would suggest to give a try to this code.
It's basic but I'm sure with a twist you can solve your problem.
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;
Usage :
LoadFile('File.txt', StringGrid1);
Beny
CodePudding user response:
Try this
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;