?
Solved

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

Posted on 2003-04-01
13
Medium Priority
?
161 Views
Last Modified: 2010-04-06
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
0
Comment
Question by:AyeshaS
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +4
13 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 8245369
can you provide a sample of your file-content?
0
 
LVL 2

Expert Comment

by:sgc_romania
ID: 8245541
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
 

Author Comment

by:AyeshaS
ID: 8245602
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 27

Expert Comment

by:kretzschmar
ID: 8245780
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
 

Author Comment

by:AyeshaS
ID: 8245883
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
 
LVL 4

Expert Comment

by:cjm30305
ID: 8245976
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
 
LVL 27

Expert Comment

by:kretzschmar
ID: 8246004
hmm, two files
0
 

Author Comment

by:AyeshaS
ID: 8252337
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
 
LVL 1

Accepted Solution

by:
nafeelm earned 80 total points
ID: 8267532

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
 
LVL 1

Expert Comment

by:nafeelm
ID: 8268717

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
 

Expert Comment

by:CleanupPing
ID: 9316509
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
 
LVL 10

Expert Comment

by:kacor
ID: 10041264
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

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses
Course of the Month12 days, 17 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question