Read values one at a time from a text file which is in colomn/row format and space delimited

Hi

I have a problem and I am sure there is an answer to it. Can someone please provide me with the code.
I would like to read a simple text file which is space delimited (2 or 3 spaces) and in a row/column format. Each row has one set of information where the first column is a combination of letters and numbers (which i will call Stations) and the rest of the columns are floats.  I want to basically read one row at a time and each value on that line until the end of the file by reading the first value until the first space is found and then the second value, and so on. And the same for the next row.
The objective is to do some calculation with the floats which belong to a particular Station.

Can somebody please help asap.
Thanx.

AyeshaS
AyeshaSAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
can you provide a sample of your file-content?
0
sgc_romaniaCommented:
try this:

var f: text;
    s, stemp:string;
    b[m]:array of string;// m is number of stations (rows)
    a[n]:array of real;//n is number of float fields = number of columns -1
    i,j,k:integer;
begin
i:=0;
assign(f, 'fileofstation.txt);
reset(f);
while not eof(f) do
begin
  readln(f,s);
  i:=i+1;
  stemp:='';
  j:=1;
  k:=1;
//fill in the station name
  while s[k]<>'' do
  begin
    stemp:=stemp+s[k];
    k:=k+1;
  end;
  b[i]:=stemp;
//fill in the floats fields regardind the current station
  while s[k]<>' ' do k:=k+1;
  stemp:='';
  while k<length(s) do
  begin
    k:=k+1;
    if s[k]<>' ' then stemp:=stemp+s[k];
    else
    begin
      if stemp<>'' then a[i,j]:=val(stemp); //if val doesn't work try strtofloat(..)
      stemp:='';
      j:=j+1;
    end;
  end;
end;
end;

end.
0
AyeshaSAuthor Commented:
here is an example of my text file content

C81A 3820 100 100
C81B 576  100 25
C81C 250  100 50
C81D 1950 100 33
C81E 643  100 62


0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

kretzschmarCommented:
well,

i have a sample for filling a stringgrid
with the file:

unit fill_stringgrid_with_file_u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  private
    procedure fillgrid(AFileName : String);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


function splitstr(var astring : String; Delimiter : String) : String;
var
  p : Integer;
begin
  result := '';
  if AString <> '' then
  begin
    p := pos(Delimiter,AString);
    if p > 0 then
    begin
      result := copy(AString,1,p-1);
      AString := copy(AString,p+length(Delimiter),maxLongInt);
    end
    else
    begin
      result := AString;
      AString := '';
    end;
  end;
end;


procedure TForm1.fillgrid(AFileName : String);
var
  sl : TStringList;
  i : integer;
  s, ssplit : string;
  splitcount : Integer;
begin
  stringgrid1.RowCount := 1;
  stringgrid1.ColCount := 0;
  stringgrid1.FixedCols := 0;
  sl := TStringList.Create;
  try
    sl.LoadFromFile(AFileName);
    for i := 0 to sl.count-1 do
    begin
      s := trim(sl[i]);
      SplitCount := 0;
      stringgrid1.RowCount := stringgrid1.RowCount + 1;
      while s <> '' do
      begin
        ssplit := splitStr(s,' ');
        s := trim(s);
        inc(SplitCount);
        if stringgrid1.ColCount < SplitCount then
          StringGrid1.ColCount := StringGrid1.ColCount + 1;
        stringgrid1.Cells[SplitCount-1,stringgrid1.RowCount-1] := ssplit;
      end;
    end;
  finally
    sl.Free;
  end;
  if stringgrid1.RowCount > 1 then
    stringgrid1.FixedRows := 1;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if opendialog1.Execute then
    fillgrid(opendialog1.FileName);
end;

end.

read one record only follows

meikl ;-)
0
AyeshaSAuthor Commented:
Thanx sqc Romania. But I do not want to read the entire line. I just want the first value until the space and then the next value, etc.
Looking at an example of the content of my text files below
File 1:
C81A  3820  100  100
C81B  576   100  25
C81C  250   100  50
C81D  1950  100  33
C81E  643   100  62

File 2:
C81A 0.25
C81B 1.2  
C81C 2.0  
C81D 5.2
C81E 0.8  

I would like to read the station (eg C81A), the value pertaining to that station in both files (eg 3820  100  100  0.25) and do a calculation on it. An then move on to another station (next row).
0
cjm30305Commented:
var
 SL: TStringList;
 i, i2: Integer;
 Col1, Col2, Col3, Col4: string;
 Delimiter: string;
 WorkingString: string;  // This will change as you take values out.  It will start out as the entire string, and then each time you take a value out, it will take it out of this as well.
begin
  Delimiter := ' '; // Set to one or two or 100 spaces.  Whatever it is.
  SL := TStringList.Create;
  SL.LoadFromFile('C:\MyTextFileWithStrings.txt');

  for i := 0 to SL.Count - 1 do
   begin
    WorkingString := SL.Strings[i];
    i2 := POS(Delimiter, WorkingString);
    Col1 := Copy(WorkingString, 1, i2);
    StringReplace(WorkingString, Col1, EmptyStr, [rfIgnoreCase]);
    i2 := POS(Delimiter, WorkingString);
    Col2 := Copy(WorkingString, 1, i2);
    StringReplace(WorkingString, Col2, EmptyStr, [rfIgnoreCase]);
    // Keep it going for each column.
   end;

  SL.Free;
end;

Cheers.
0
kretzschmarCommented:
hmm, two files
0
AyeshaSAuthor Commented:
Yes two files.
The first colmn of both files has the same info (the Station number)but in different order and the other colmns has values (float). i have to do a calculation with these values for each stations but i cant do that tif i cant read it in one at a time.  All im supplied is text files.
0
nafeelmCommented:

will this always be in a sorted order (station no. wise) as mentioned below:

File 1:
C81A  3820  100  100
C81B  576   100  25
C81C  250   100  50
C81D  1950  100  33
C81E  643   100  62

File 2:
C81A 0.25
C81B 1.2  
C81C 2.0  
C81D 5.2
C81E 0.8  

and max. how many files would u be processing 2 or more?

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
nafeelmCommented:

I have used
2 ListBox(ListBox1, ListBox2) set ListBox2.Sorted:=True
and a StringGrid Component to meet your requirements.



In the proposed example you can use 'n' number of files for processing!


I have written 4 procedures
procedure LoadTextFromFile;  //Loads Data From File
procedure DeleteExtraSpaces; //Deletes spaces within the string
procedure CombineSameStationData; //Combines your station data
procedure WriteDataIntoGrid; // displays it row-wise within StringGrid  .. this data written in the Grid can be used for calculating values the way u want!



procedure TForm1.LoadTextFromFile;
begin
  // you can put this in a loop to specify the list of files u want to process
  // as of now i have treated it to be getting data from 2 text files
  listbox1.Items.Clear;
  listbox2.Items.Clear;
  listbox1.Items.LoadFromFile('c:\windows\desktop\t1.txt'); // file names
  listbox2.Items.AddStrings(ListBox1.Items);
  listbox1.Items.LoadFromFile('c:\windows\desktop\t2.txt'); // file names
  listbox2.Items.AddStrings(ListBox1.Items);
end;

procedure TForm1.DeleteExtraSpaces;
var i,j : Integer; DStr: String;
begin
//i & j are counter variables of the ListBox
//DStr is a String variable which holds individual entry of the listbox
  with Listbox2 do
  begin
    for i:=0 to Items.Count - 1 do
    begin
      DStr:=ListBox2.Items[i];

      j:=1;
      while j <= Length(DStr) do
      begin
        if (DStr[j] = ' ') and (DStr[j+1] = ' ') then
          Delete(DStr,j,1)
        else
          j:=j+1;
      end;
      ListBox2.Items[i]:=DStr;
    end;
  end;
end;

procedure TForm1.CombineSameStationData;
var i: Integer; DStr, MStr: String;
begin
//i & j are counter variables of the ListBox
//DStr & MStr are String variable which holds individual entry of the listbox
  with Listbox2 do
  begin
    i:=0;
    while i <= Items.Count - 1 do
    begin
      DStr:=ListBox2.Items[i];
      MStr:=ListBox2.Items[i+1];

      if Copy(DStr, 1, Pos(' ',DStr)) = Copy(MStr, 1, Pos(' ',MStr)) then
      begin
        ListBox2.Items[i]:=DStr+' '+Copy(MStr, Pos(' ',MStr)+1, Length(MStr));
        ListBox2.Items.Delete(i+1);
      end;
      i:=i+1;
    end;
  end;
end;

procedure TForm1.WriteDataIntoGrid;
var i, j, r, c, LP: Integer; DStr: String;
begin
//i & j are counter variables of the ListBox
//c & r are column, row variables of the StringGrid
//LP is a variable to track last position where the space was found
  with Listbox2 do
  begin
    r:=0;
    for i:=0 to Items.Count - 1 do
    begin
      LP:=1;
      c:=0;
      DStr:=ListBox2.Items[i];

      for j:=1 to Length(DStr) do
      begin
        if (DStr[j]=' ') or (j = Length(DStr)) then
        begin
          StringGrid1.Cells[c,r]:=Copy(DStr, LP, j-LP+1);
          LP:=j+1;
          c:=c+1;
        end;
      end;
      if StringGrid1.ColCount < c then StringGrid1.ColCount:=c;
      r:=r+1;
    end;
    StringGrid1.RowCount:=r;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  LoadTextFromFile;
  DeleteExtraSpaces;
  CombineSameStationData;
  WriteDataIntoGrid;
end;


let me know if this solves your purpose!

-nafeel-

0
CleanupPingCommented:
AyeshaS:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
kacorretiredCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:
       to accept nafeelm's answer
Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

kacor
EE Cleanup Volunteer
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.