My Task is....(this is in pascal code by the way i am using a software called pascal7)

Produce a program that:
*reads in, from a text file, the names and dates of birth of 5 people
*stores these names and dates of birth using a sensible data structure
*determines which person is the oldest
*writes to the screen the name and age (in years) of the oldest person.

My text file i wrote in windows notepad heres whats in it:

Rachel Aspinall
7/01/1993

Heather Aspinall
28/12/1990

Laura Prescott
17/02/1991

Simon Jenkins
20/03/1991

Ross Harrison
30/02/1990

And heres my code ive written in pascal so far:

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
FileA:TextFile;
s: string;


begin

Assign(FileA,'PeopleInformation.txt');
Reset(FileA);
while not EOF(FileA) do
begin
Readln(FileA,s);
end;


end.

The code ive written so far is the first bullet point can someone help me with the other bullet points im desperate! i spent 5 hours on it yesterday and didnt get anywere i know i have to do an array i just dont know were to start please help

Recommended Answers

All 18 Replies

Whenever you read the word "structure" always think record (or class, but you haven't gotten that far yet...).

So create a record with a string for the person's name and some numbers for his birth date.

Then, when reading the file, be careful to pay attention to the shape of the input. In this case, each input record has three lines:
name
birth date
blank line
So for each record you read you will have to read three lines.

You can use dynamic arrays, but if you haven't been taught that yet, just make an array of 100 or so records, and count how many records you put in the array as you read the file.

while not eof do
  begin
  read record
  number_of_records := number_of_records + 1;
  store the record you just read at the next empty location in the array
  end

Then just loop through the array and find index of the oldest person. Once done, print that record.

Hope this helps.

Ive written this ... as a type

type Tperson = record
Name: string;
Dateofbirth: TDateTime;
end;{record}

i dont understand do i write anything else on my text document, seen on my last post?

how does it know what type i want?

what else do i add as a vairable would i put FileA:file of tperson ?

That is a very good start. Now all you need to do is read data from the file and stick it in the record.

For the following examples, I have the hypothetical variable: var person: tPerson; The first thing to read is a string, all by itself on a line, so readln( fileA, person.name ); works just fine.

In the Delphi IDE, place the cursor over the word TDateTime and press F1. You'll get the help for that type. Up at the top there is a link that says See also. This will give you a list of things related to the tDateTime, including functions to read and write it from string. I found StrToDate in the list. So, you can read the next line as:

var dateString: string;
...
readln( fileA, dateString );
person.dateOfBirth = strToDate( dateString );

Don't forget that there is still that blank line to read: readln( fileA ); Put these three together and you have read a single record from file and stored it in a Pascal-style record.

You could make a function that does this for you:

function readPersonRecordFromFile( var file: TextFile ): tPerson;
  var dateStr: string;
  begin
  readln( file, result.name );
  readln( file, dateStr );
  result.dateOfBirth = strToDate( dateStr );
  readln( file )
  end;

Keep working at it. Hope this helps.

PS. I'm not too fond of just giving code away when you are learning something new. Please pay attention to the thought process that went into creating this function. Now, you must still use the function to read all the "records" in the file into your array of tPerson.

Er, it just occurred to me that file is a reserved word, not a directive, so it is illegal to use as a variable name. Also, I made a syntax error (using = instead of :=). So the code should be:

function readPersonRecordFromFile( var f: TextFile ): tPerson;
  var dateStr: string;
  begin
  readln( f, result.name );
  readln( f, dateStr );
  result.dateOfBirth := strToDate( dateStr );
  readln( f )
  end;

I'd have edited my last post but it seems that after a certain amount of time passes you can't...

Sorry. Hope this helps.

An error occured when i tryed to play my code
heres what my code looks like:

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;


type Tperson = record
Name:String;
Dateofbirth:TDateTime;
end;{record}


var

s: string;
personinfo:Tperson;
FileA:textfile;
datestring:string;

begin

Assign(FileA,'PeopleInformation.txt');
Reset(FileA);
while not EOF(FileA) do
begin
Readln(FileA,s);
end;
close(FileA);
Reset (FileA);
while not EOF(FileA) do
begin
Readln (FileA,personinfo.name);
Readln (FileA,datestring);
personinfo.Dateofbirth:=strToDate(datestring);
Readln ( FileA );
end;

end.

It says 28/12/1990 is not a valid date but it is sint it?
I would also like to thank you for your help so far it is much appreicated

Please use [[I][/I]code[I][/I]] blocks...

The default date format is 'm/d/yyyy', which is typical in the USA. I didn't look that closely at your dates... Before you call StrToDate say: ShortDateFormat := 'd/mm/yyyy'; Now the date/time functions will work.

The last date in your input is 30/02/1990 --which is invalid. February has no more than 29 days... and 1990 is not a leap year so the latest day in February is 28/02/1990.

Sorry about that.

ok ive sorted that error now because i just turned all my dates as 01/12/1990, 02/12/1990 ect..

but when i play the program it comes up as :

0.00000000000E+0000

heres my code:

var

s: string;
FileA:textfile;
datestring:string;
personarray:array [1..5] of Tperson;
personinfo:Tperson;
I:Integer;


begin

Assign(FileA,'PeopleInformation.txt');
Reset(FileA);
while not EOF(FileA) do
begin
Readln(FileA,s);
end;
close(FileA);
Reset (FileA);
while not EOF(FileA) do
begin
Readln (FileA,personinfo.name);
Readln (FileA,datestring);
personinfo.Dateofbirth:=strToDate(datestring);
Readln ( FileA );
end;
writeln (personarray[1].name, personarray[1].Dateofbirth);
readln;

end.

I dont understand why its doing this everthing seems to be fine

ok now i have no date errors but again when i want to play the program it comes up as 00000000E+0000

heres my code:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;




 type Tperson = record
 Name:String;
 Dateofbirth:TDateTime;
 end;{record}




var

s: string;
FileA:textfile;
datestring:string;
personarray:array [1..5] of Tperson;
personinfo:Tperson;
I:Integer;


begin

   Assign(FileA,'PeopleInformation.txt');
   Reset(FileA);
   while not EOF(FileA) do
      begin
      Readln(FileA,s);
      end;
 close(FileA);
 Reset (FileA);
 while not EOF(FileA) do
 begin
 Readln (FileA,personinfo.name);
 Readln (FileA,datestring);
 ShortDateFormat := 'd/mm/yyyy';
 personinfo.Dateofbirth:=strToDate(datestring);
 Readln ( FileA );
 end;
 writeln (personarray[1].name, personarray[1].Dateofbirth);
 readln;















end.

hey i edited my code again this time i know for certain its too do with the date when i do writeln (personinfo.name, personinfo.Dateofbirth);
readln; the date of birth displays like this:3.4000+E 0000

heres my code again

Dateofbirth:TDateTime;
 end;{record}




var

s: string;
FileA:textfile;
datestring:string;
personinfo:Tperson;
I:Integer;


begin
   //Read whats on the text file:
   Assign(FileA,'PeopleInformation.txt');
   ShortDateFormat := 'dd/mm/yyyy';
   Reset(FileA);
   while not EOF(FileA) do
      begin
      Readln(FileA,s);
      end;
      //Store data from text file as types:
 close(FileA);
 Reset (FileA);
 while not EOF(FileA) do
 begin
 Readln (FileA,personinfo.name);
 Readln (FileA,datestring);
 personinfo.Dateofbirth:=strToDate( datestring );
 Readln ( FileA );
 end;
 writeln (personinfo.name, personinfo.Dateofbirth);
 readln;















end.

Hey there. Here is your code more carefully formatted and with some commentary.

program Project1;
{$APPTYPE CONSOLE}
uses
  SysUtils;

type
  Tperson = record
            Name:        String;
            Dateofbirth: TDateTime;
            end;

var
  s:           string;
  FileA:       textfile;
  datestring:  string;
  personarray: array [1..5] of Tperson;  // very good
  personinfo:  Tperson;
  I:           Integer;


begin
  // You only need to set this global value once
  ShortDateFormat := 'd/mm/yyyy';

  // Good
  Assign(FileA,'PeopleInformation.txt');

  // The following reads each line of the file but
  // does nothing with it...
  Reset(FileA);
  while not EOF(FileA) do
    begin
    Readln(FileA,s);
    // See note 1
    end;
  close(FileA);

  // The following is a loop that properly reads each
  // record from file. However, like the first loop's 
  // s:string variable, the information is never used;
  // it is forgotten the next time through the loop.
  // See note 2
  Reset (FileA);
  while not EOF(FileA) do
    begin
    Readln (FileA,personinfo.name);
    Readln (FileA,datestring);
    personinfo.Dateofbirth:=strToDate(datestring);
    Readln ( FileA );
    end;

  // Here you try to print a variable you never initialized.
  // See note 3
  writeln (personarray[1].name, personarray[1].Dateofbirth);

  // Wait for the user to press ENTER before terminating
  readln;

end.

Note 1
Perhaps you made this loop because you wanted to see the file before putting it in a TPerson record? If so, replace the // See note 1 coment with: writeln( s ); Otherwise, you keep giving s a new value each time through the loop but you never actually use it. Neither s nor the loop have any purpose --you could just delete it and the code would work the same.


Note 2
As already noted, you are making the same error here with personinfo as you did with s above. Each time through the loop you initialize it properly, but you never use it before initializing it again with a new person's data.

I think what you wanted to do is replace personinfo.[I]something[/I] with personarray[ i ].[I]something[/I] This means though that you will have to use i as well. Before starting the loop set it to 1 and increment it by one at the end of each loop.


Note 3
You should always give a variable a value before you use it. Since you did not store your records in personarray (see note 2), but only in personinfo, the only variable that has information read from file is personinfo, and it is only the very last record in the file (Ross Harrison).

The problem you are having with the funny "00000000E+0000" output is this: since you never gave the personarray[1] record a value, the Name string is the empty string ('', i.e. a string with no characters in it), and the DateOfBirth is zero. So, when you ask to writeln( [I]myperson[/I].Name, [I]myperson[/I].DateOfBirth ); it does just that, first printing

then printing 00000000E+0000 TDateTime is stored as a floating point double, so that is why the weird output. Remember you must use the StrToDate and DateToStr functions to convert a string to or from a tDateTime.

Hope this helps.

thanks for the effort you have put in for helping me its really appreciated
when you say : "TDateTime is stored as a floating point double"

what is that

It doesn't matter. Just use the supplied functions to convert it to/from a string.

(I'm not being rude here. You should not care how it is actually stored in memory --only how to use it. I shouldn't have mentioned its storage type.)

If you want to learn more about floating-point data types see the section "Data types, variables, and constants" chapter in the Object Pascal Reference that came with Delphi.

ive looked through your notes carefully and corrected my mistakes but im still having the same problem when reading the date it shows:
rachel aspinall 3.400E 00000

my edited code:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,DateUtils;




 type Tperson = record
 Name:String;
 Dateofbirth: TDateTime;
 end;{record}




var


FileA:textfile;
datestring:string;
personarray:array [1..5] of Tperson;

I:Integer;




begin

ShortDateFormat := 'd/mm/yyyy';
   //Read whats on the text file:
   Assign(FileA,'PeopleInformation.txt');

   Reset(FileA);
 I:=1;
 while not EOF(FileA) do
 begin
 Readln (FileA,personarray[I].name);
 Readln (FileA,datestring);
 personarray[I].Dateofbirth:=strTodate(datestring);

 Readln ( FileA );
 I:=+1
 end;

 writeln (personarray[1].name, personarray[1].Dateofbirth);
 readln;
















end.

The writeln procedure only knows how to format and write certain types of things: all of the simple data types (integer, byte, word, char, single, double, boolean, etc.) and strings. It is blissfully ignorant about everything else.

Hence, you can't say writeln( personinfo ); --it just doesn't know how. The same is true of readln. You had to read into strings and convert things as needed.

Remember when you read the date you had to say readln( dateStr ); personarray[ i ].dateOfBirth := strToDate( dateStr ); That's because TDateTime is an abstract data type, and you need functions to convert it to and from a string.

uses SysUtils;
var
  d: tDateTime;
  s: string;
begin
write( 'Please enter a date as M/D/Y: ' );
readln( s );
try
  d := strToDate( s )
except
  writeln( 'You did not enter a valid date.' );
  halt
  end;
ShortDateFormat := 'mmmm d, yyyy';
writeln( 'The date you entered was ', dateToStr( d ) )
end.

thanks

Glad to have been of help. :)

o i have another error for some reason evertime i try to play the program it goes : invalid date i dont understand because my text file is fine

text file:
Heather Aspinall
28/12/1990

Simon Jenkins
12/10/1991

Ross Harrison
14/10/1992

Rachel Aspinall
07/01/1993

Laura Prescott
12/09/1994

my code:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,DateUtils;




 type Tperson = record
 Name:String;
 Dateofbirth: TDateTime;
 end;{record}




var


FileA:textfile;
datestring:string;
personarray:array [1..5] of Tperson;
Dateofbirth1,Dateofbirth2,Dateofbirth3,Dateofbirth4,Dateofbirth5:string;

I:Integer;




begin


   //Read whats on the text file:
   ShortDateFormat := 'dd/mm/yyyy';
   Assign(FileA,'PeopleInformation.txt');

   Reset(FileA);
 I:=1;
 while not EOF(FileA) do
 begin

 Readln (FileA,personarray[I].name);
 Readln (FileA,datestring);
 personarray[I].Dateofbirth:=StrToDate(datestring);
 Readln ( FileA );
 I:=I+1;
 end;

Dateofbirth1:= dateToStr( personarray[1].Dateofbirth ) ;
Dateofbirth2:= dateToStr( personarray[2].Dateofbirth ) ;
Dateofbirth3:= dateToStr( personarray[3].Dateofbirth ) ;
Dateofbirth4:= dateToStr( personarray[4].Dateofbirth ) ;
Dateofbirth5:= dateToStr( personarray[5].Dateofbirth ) ;





writeln ('The oldest person is: ');
writeln (personarray[1].name );
readln;



























end.

I don't know. It works fine on my end.

Question: why all the DateOfBirth1,... strings?

If you want to know which date is older just compare them:

var d1, d2: tDateTime;
begin
  d1 := strToDate( '28/10/2007' );
  d2 := strToDate( '29/10/2007' );
  if d1 < d2
    then writeln( 'correct: the 28th comes before the 29th' )
    else writeln( 'error: apparently the 29th comes before the 28th...' )
end.

You already have all the dates in your array. Just find the record that has the oldest date and print that record.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.