0% found this document useful (0 votes)
22 views

PASCAL Lab Activiti Start Programming

Uploaded by

eliaschilufya250
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

PASCAL Lab Activiti Start Programming

Uploaded by

eliaschilufya250
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

Start programming

using
Object Pascal
Chapter One
Language Basics
Our First Application
After installing and running Lazarus, we can start a new program from the main menu:
Project/New Project/Program
We will get this code in the Source Editor window:

program helloWorld(input, output);


uses crt;
begin
clrscr;
writeln(‘Hello World’);
readkey;
end.

program findEvenOrOdd(input, output);


var num1:integer;
begin
writeln(‘Please enter your number’);
read(num1); {assigns user input as num1}
if(num1 MOD 2 = 0) then
writeln(‘Your number is Even’)
else
writeln(‘Your number is Odd’);
end.

Compiled by Engineer Mulimbi Bricious 1


Program findEvenOrOdd(input, output);
uses crt;
var num1:integer;
begin
clrscr;
Writeln(‘Please enter your number’);
Read(num1);
If(num1 MOD 2 =0) then
Writeln(‘Your number is Even’)
else
writeln(‘Your number is Odd’);
readkey;
end.

Program displayresults(input, output);


uses crt;
var marks : integer;
var grade : char;
begin
clrscr;
Write(‘Enter your marks : ’);
Read(marks);
str :=’Your result is ’;
if(marks>= 0) AND (marks<= 100) then
if (marks>=75) then
writeln(str, ‘A’)
else if (marks >=65) then
writeln(str, ‘B’)
else if (marks >=55) then
writeln(str, ‘C’)
else if (marks >=35) then
writeln(str, ‘S’)
else
writeln(str, ‘W’)
else
writeln(‘Invalid marks’);
readkey;
end.

Compiled by Engineer Mulimbi Bricious 2


Program displayresults(input, output);
uses crt;
var marks : integer;
var grade : char;
begin
clrscr;
Write(‘Enter your marks : ’);
Read(marks);
case marks of
0..34 : grade := ‘W’;
35..54 : grade := ‘S’;
55..64 : grade := ‘C’;
65..74 : grade := ‘B’;
75..100 : grade := ‘A’;
else
writeln(‘Invalid marks’);
end;
if(marks>=) AND (marks <= 100) then
writeln(‘Your grade is’, grade);
readkey;
end.

program linesoftext(output);
begin
writeln('hi there.');
writeln('how are you today?');
writeln('are you ready for pascal?')
end.

Write a Pascal program to display the following text on the screen:


MuliZambia Corperation.
-------------------------
23645 Kabanana Sit and Service
Lusaka Zambia

PROGRAM CrunchNumbers(OUTPUT);
BEGIN
writeln('i can easily crunch numbers.');
writeln('here is multiplication of 50x4:',50*4);
writeln('..and here is division of 2400/8:',2400/8)
END.

Compiled by Engineer Mulimbi Bricious 3


PROGRAM Variables(OUTPUT);
{ Variable Declarations }
VAR
a, b :INTEGER;
x :REAL;
{ Program Block }
BEGIN
writeln('contents of a=',a);
writeln('contents of b=',b);
writeln('contents of x=',x)
END.

program arithmetic(output);
{ variable declarations }
var
a, b :integer;
{ program block }
begin
a := 25;
b := 2;
writeln('a=',a);
writeln('b=',b);
writeln('a+b=',a+b);
writeln('a–b=',a–b);
writeln('a*b=',a*b);
writeln('a/b=',a/b);
writeln('a div b=',a div b); {used with integers only}
writeln('a mod b=',a mod b) {used with integers only}
end.

program constants(output);
{ constant declarations }
const
pi = 3.14159;
{ variable declarations }
var
radius, perimeter :real;
{ program block }
begin
radius := 4.9;
perimeter := 2 * pi * radius;
writeln('perimeter=', perimeter)
end.

Compiled by Engineer Mulimbi Bricious 4


program functions1(output);
{ constant declarations }
const
pi = 3.14159;
{ variable declarations }
var
perimeter, radius :real;
roundedperimeter, truncatedperimeter :integer;
{ program block }
begin
radius := 4.9;
perimeter := 2*pi*radius;
roundedperimeter := round(perimeter);
truncatedperimeter := trunc(perimeter);
writeln('perimeter=', perimeter);
writeln('perimeter (rounded)=', roundedperimeter);
writeln('perimeter (truncated)=', truncatedperimeter)
end.

program keyboardinput(output);
{ constant declarations }
const
pi = 3.14159;
{ variable declarations }
var
perimeter, radius :real;
roundedperimeter, truncatedperimeter :integer;
{ program block }
begin
write('please enter the radius:');
readln(radius);
perimeter := 2*pi*radius;
roundedperimeter := round(perimeter);
truncatedperimeter := trunc(perimeter);
writeln('perimeter=', perimeter);
writeln('perimeter (rounded)=', roundedperimeter);
writeln('perimeter (truncated)=', truncatedperimeter)
end.

Compiled by Engineer Mulimbi Bricious 5


PROGRAM Format(OUTPUT);
{ Variable Declarations }
VAR
a :INTEGER;
b :REAL;
{ Program Block }
BEGIN
b := 1.2e+02;
a := 320;
writeln('i am a text string starting from position 1.');
writeln('i am now shifted to the right end of the field.':50);
writeln('i am an unformatted integer:', a);
writeln('i am an integer written in a field 6 characters wide:', a:6);
writeln('i am a money amount written in 8 positions:$',b:8:2);
writeln('i am a money amount shifted to the left:$',b:0:2)
END.

program first;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
{$IFDEF WINDOWS}{$R first.rc}{$ENDIF}
begin
Writeln('This is Free Pascal and Lazarus');
Writeln('Press enter key to close');
Readln;
end.

Other examples
In the previous program change this line:
Writeln('This is Free Pascal and Lazarus');
to this one:
Writeln('This is a number: ', 15);
Then press F9 to run the application. You will get this result: This is a number: 15
Change the previous line as shown below, and run the application each time:
Code:
Writeln('This is a number: ', 3 + 2);
Output:
This is a number: 5
Code:
Writeln('5 * 2 = ', 5 * 2);
Output:

Compiled by Engineer Mulimbi Bricious 6


5 * 2 = 10
Code:
Writeln('This is real number: ', 7.2);
Output:
This is real number: 7.2000000000000E+0000
Code:
Writeln('One, Two, Three : ', 1, 2, 3);
Output:
One, Two, Three : 123
Code:
Writeln(10, ' * ', 3 , ' = ', 10 * 3);
Output:
10 * 3 = 30
We can write different values in the Writeln statement each time and see the result. This
will help us understand it clearly.

Variables
Variables are data containers. For example, when we say that X = 5, that means X is a
variable, and it contains the value 5. Object Pascal is a strongly typed language, which
means we should declare a variable's type before putting values into it. If we declare X
as an integer, that means we should put only integer numbers into X during its life time in
the application.

Examples of declaring and using variables:

program FirstVar;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
var
x: Integer;
begin
x:= 5;
Writeln(x * 2);
Writeln('Press enter key to close');
Readln;
end.

We will get 10 in the application's output. Note that we used the reserved word Var,
which means the following lines will be variable declarations:
x: Integer;
This means two things:

Compiled by Engineer Mulimbi Bricious 7


1. The variable's name is X; and
2. the type of this variable is Integer, which can hold only integer numbers without a
fraction. It could also hold negative values as well as positive values. And the
statement:
x:= 5;
means put the value 5 in the variable X.
In the next example we have added the variable Y:

var
x, y: Integer;
begin
x:= 5;
y:= 10;
Writeln(x * y);
Writeln('Press enter key to close');
Readln;
end.

The output of the previous application is:


50
Press enter key to close
50 is the result of the formula (x * y).
In the next example we introduce a new data type called character:

var
c: Char;
begin
c:= 'M';
Writeln('My first letter is: ', c);
Writeln('Press enter key to close');
Readln;
end.
This type can hold only one letter, or a number as an alphanumeric character, not as
value. In the next example we introduce the real number type, which can have a
fractional part:

var
x: Single;
begin
x:= 1.8;
Writeln('My Car engine capacity is ', x, ' liters');
Writeln('Press enter key to close');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 8


To write more interactive and flexible applications, we need to accept input from the user.
For example, we could ask the user to enter a number, and then get this number from the
user input using the Readln statement / procedure:

var
x: Integer;
begin
Write('Please input any number:');
Readln(x);
Writeln('You have entered: ', x);
Writeln('Press enter key to close');
Readln;
end.

In this example, assigning a value to X is done through the keyboard instead ofassigning
it a constant value in the application. In the example below we show a multiplication table
for a number entered by the user:

program MultTable;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
var
x: Integer;
begin
Write('Please input any number:');
Readln(x);
Writeln(x, ' * 1 = ', x * 1);
Writeln(x, ' * 2 = ', x * 2);
Writeln(x, ' * 3 = ', x * 3);
Writeln(x, ' * 4 = ', x * 4);
Writeln(x, ' * 5 = ', x * 5);
Writeln(x, ' * 6 = ', x * 6);
Writeln(x, ' * 7 = ', x * 7);
Writeln(x, ' * 8 = ', x * 8);
Writeln(x, ' * 9 = ', x * 9);
Writeln(x, ' * 10 = ', x * 10);
Writeln(x, ' * 11 = ', x * 11);
Writeln(x, ' * 12 = ', x * 12);
Writeln('Press enter key to close');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 9


Note that in the previous example all the text between single quotation marks (') is
displayed in the console window as is, for example: ' * 1 = ' Variables and expressions
that are written without single quotation marks are evaluated and written as values.

See the difference between the two statements below:


Writeln('5 * 3');
Writeln(5 * 3);
The result of first statement is:
5*3
Result of the second statement is evaluated then displayed:
15
In the next example, we will do mathematical operations on two numbers (x, y), and we
will put the result in a third variable (Res):

var
x, y: Integer;
Res: Single;
begin
Write('Input a number: ');
Readln(x);
Write('Input another number: ');
Readln(y);
Res:= x / y;
Writeln(x, ' / ', y, ' = ', Res);
Writeln('Press enter key to close');
Readln;
end.

Since the operation is division, it might result in a number with a fraction, so for that reason
we have declared the Result variable (Res) as a real number (Single). Single means a
real number with single precision floating point.

Sub types
There are many sub types for variables, for example, Integer number subtypes differ in
the range and the number of required bytes to store values in memory. The table below
contains integer types, value ranges, and required bytes in memory: Type Min value Max
Value Size in Bytes

Compiled by Engineer Mulimbi Bricious 10


We can get the minimum and maximum values and bytes sizes for each type by using
the Low, High, and SizeOf functions respectively, as in the example below:

program Types;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes;
begin
Writeln('Byte: Size = ', SizeOf(Byte),
', Minimum value = ', Low(Byte), ', Maximum value = ',
High(Byte));
Writeln('Integer: Size = ', SizeOf(Integer),
', Minimum value = ', Low(Integer), ', Maximum value = ',
High(Integer));
Write('Press enter key to close');
Readln;
end.

Conditional Branching
One of the most important features of intelligent devices (like computers, programmable
devices) is that they can take actions in different conditions. This can be done by using
conditional branching. For example, some cars lock the door when the speed reaches or
exceeds 40 K/h. The condition in this case will be: If speed is >= 40 and doors are
unlocked, then lock door. Cars, washing machines, and many other gadgets contains
programmable circuits like micro controllers, or small processors like ARM. Such circuits
can be programmed using assembly, C, or Free Pascal according to their architecture.

Compiled by Engineer Mulimbi Bricious 11


The If condition
The If condition statement in the Pascal language is very easy and clear. In the example
below, we want to decide whether to turn on the airconditioner or turn it off, according to
the entered room temperature:

AirConditioner
program:
var
Temp: Single;
begin
Write('Please enter Temperature of this room :');
Readln(Temp);
if Temp > 22 then
Writeln('Please turn on air-condition')
else
Writeln('Please turn off air-condition');
Write('Press enter key to close');
Readln;
end.

We have introduced the if then else statement, and in this example: if the temperature is
greater than 22, then display the first sentence:: Please turn on air-conditionerelse, if the
condition is not met (less than or equal to 22) , then display this line: Please turn off air-
conditioner
We can write multiple conditions like:

var
Temp: Single;
begin
Write('Please enter Temperature of this room :');
Readln(Temp);
if Temp > 22 then
Writeln('Please turn on air-conditioner')
else
if Temp < 18 then
Writeln('Please turn off air-conditioner')
else
Writeln('Do nothing');
You can test the above example with different temperature values to see the
results. We can make conditions more complex to be more useful:

var
Temp: Single;
ACIsOn: Byte;

Compiled by Engineer Mulimbi Bricious 12


begin
Write('Please enter Temperature of this room : ');
Readln(Temp);
Write('Is air conditioner on? if it is (On) write 1,',
' if it is (Off) write 0 : ');
Readln(ACIsOn);
if (ACIsOn = 1) and (Temp > 22) then
Writeln('Do nothing, we still need cooling')
else
if (ACIsOn = 1) and (Temp < 18) then
Writeln('Please turn off air-conditioner')
else
if (ACIsOn = 0) and (Temp < 18) then
Writeln('Do nothing, it is still cold')
else
if (ACIsOn = 0) and (Temp > 22) then
Writeln('Please turn on air-conditioner')
else
Writeln('Please enter a valid values');
Write('Press enter key to close');
Readln;
end.

In the above example, we have used the new keyword (and) which means if the first
condition returns True (ACIsOn = 1), and the second condition returns True (Temp > 22),
then execute the Writeln statement. If one condition or both of them return False, then it
will go to the else part. If the airconditioner is connected to a computer via the serial port
for example, then we can turn it on/off from that application, using serial port
procedures/components. In this case we need to add extra parameters for the if condition,
like for how long the airconditioner was operating. If it exceeds the allowable time (for
example, 1 hour) then it should be turned off regardless of room temperature. Also we
can consider the rate of losing coolness, if it is very slow (at night), then we could turn if
off for longer time.

Weight program
In this example, we ask the user to enter his/her height in meters, and weight in Kilos.
Then the program will calculate the suitable weight for that person according to the
entered data, and then it will tell him/her the results:

program Weight;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}

Compiled by Engineer Mulimbi Bricious 13


Classes, SysUtils
{ you can add units after this };
var
Height: Double;
Weight: Double;
IdealWeight: Double;
begin
Write('What is your height in meters (e.g. 1.8 meter) : ');
Readln(Height);
Write('What is your weight in kilos : ');
Readln(Weight);
if Height >= 1.4 then
IdealWeight:= (Height - 1) * 100
else
IdealWeight:= Height * 20;
if (Height < 0.4) or (Height > 2.5) or (Weight < 3) or
(Weight > 200) then
begin
Writeln('Invalid values');
Writeln('Please enter proper values');
end
else
if IdealWeight = Weight then
Writeln('Your weight is suitable')
else
if IdealWeight > Weight then
Writeln('You are under weight, you need more ',
Format('%.2f', [IdealWeight - Weight]), ' Kilos')
else
Writeln('You are over weight, you need to lose ',
Format('%.2f', [Weight - IdealWeight]), ' Kilos');
Write('Press enter key to close');
Readln;
end.

In this example, we have used new keywords:


1. Double: which is similar to Single. Both of them are real numbers, but Double has a
double precision floating point, and it requires 8 bytes in memory, while single
requires only 4 bytes.
2. The second new thing is the keyword (Or) and we have used it to check if one of the
conditions is met or not. If one of condition is met, then it will execute the statement.
For example: if the first condition returns True (Height < 0.4), then the Writeln
statement will be called: Writeln('Invalid values'); . If the first condition returns False,
then it will check the second one, etc. If all conditions returns False, it will go to the
else part.

Compiled by Engineer Mulimbi Bricious 14


3. We have used the keywords begin end with the if statement, because if statement
should execute one statement. Begin end converts multiple statements to be
considered as one block (statement), then multiple statements could be executed by
if condition. Look for these two statemetns:

Writeln('Invalid values');
Writeln('Please enter proper values');
It has been converted to one statement using begin end:
if (Height < 0.4) or (Height > 2.5) or (Weight < 3) or
(Weight > 200) then
begin
Writeln('Invalid values');
Writeln('Please enter proper values');
end
4. We have used the procedure Format, which displays values in a specific format. In
this case we need to display only 2 digits after the decimal point. We need to add the
SysUtils unit to the

Uses clause in order to use this function.


What is your height in meters (e.g. 1.8 meter) : 1.8
What is your weight in kilos : 60.2
You are under weight, you need more 19.80 Kilos
Note:
This example may be not 100% accurate. You can search the web for weight calculation
in detail. We meant only to explain how the programmer could solve such problems and
do good analysis of the subject to produce reliable applications.

Case .. of statement
There is another method for conditional branching, which is the Case .. Of statement. It
branches execution according to the case ordinal value. The Restaurant program will
illustrate the use of the case of statement:

Restaurant program
var
Meal: Byte;
begin
Writeln('Welcome to Pascal Restaurant. Please select your order');
Writeln('1 - Chicken (10$)');
Writeln('2 - Fish (7$)');
Writeln('3 - Meat (8$)');
Writeln('4 – Salad (2$)');
Writeln('5 - Orange Juice (1$)');
Writeln('6 - Milk (1$)');
Compiled by Engineer Mulimbi Bricious 15
Writeln;
Write('Please enter your selection: ');
Readln(Meal);
case Meal of
1: Writeln('You have ordered Chicken,',
' this will take 15 minutes');
2: Writeln('You have ordered Fish, this will take 12 minutes');
3: Writeln('You have ordered meat, this will take 18 minutes');
4: Writeln('You have ordered Salad, this will take 5 minutes');
5: Writeln('You have ordered Orange juice,',
' this will take 2 minutes');
6: Writeln('You have ordered Milk, this will take 1 minute');
else
Writeln('Wrong entry');
end;
Write('Press enter key to close');
Readln;
end.

If we write the same application using the if condition, it will become more complicated,
and willcontain duplications:

Restaurant program using If condition


var
Meal: Byte;
begin
Writeln('Welcome to Pascal restaurant, please select your meal');
Writeln('1 - Chicken (10$)');
Writeln('2 - Fish (7$)');
Writeln('3 - Meat (8$)');
Writeln('4 - Salad (2$)');
Writeln('5 - Orange Juice (1$)');
Writeln('6 - Milk (1$)');
Writeln;
Write('Please enter your selection: ');
Readln(Meal);
if Meal = 1 then
Writeln('You have ordered Chicken, this will take 15 minutes')
else
if Meal = 2 then
Writeln('You have ordered Fish, this will take 12 minutes')
else
if Meal = 3 then
Writeln('You have ordered meat, this will take 18 minutes')

Compiled by Engineer Mulimbi Bricious 16


else
if Meal = 4 then
Writeln('You have ordered Salad, this will take 5 minutes')
else
if Meal = 5 then
Writeln('You have ordered Orange juice,' ,
' this will take 2 minutes')
else
if Meal = 6 then
Writeln('You have ordered Milk, this will take 1 minute')
else
Writeln('Wrong entry');
Write('Press enter key to close');
Readln;
end.

In the next example, the application evaluates students' marks and converts them to
grades: A, B, C, D, E, and F:

Students' Grades program


var
Mark: Integer;
begin
Write('Please enter student mark: ');
Readln(Mark);
Writeln;
case Mark of
0 .. 39 : Writeln('Student grade is: F');
40 .. 49: Writeln('Student grade is: E');
50 .. 59: Writeln('Student grade is: D');
60 .. 69: Writeln('Student grade is: C');
70 .. 84: Writeln('Student grade is: B');
85 .. 100: Writeln('Student grade is: A');
else
Writeln('Wrong mark');
end;
Write('Press enter key to close');
Readln;
end.

In the previous sample we have used a range, like (0 .. 39), which means the condition
will return True if the Mark value exists in this range.

Compiled by Engineer Mulimbi Bricious 17


Note:
The Case statement works only with ordinal types like Integers, char, but it doesn't work
with other types like strings, and real numbers.

Keyboard program
In this example, we will get a character from keyboard and the application will tell us the
row number of the entered key on the keyboard:

var
Key: Char;
begin
Write('Please enter any English letter: ');
Readln(Key);
Writeln;
case Key of
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p':
Writeln('This is in the second row in keyboard');
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l':
Writeln('This is in the third row in keyboard');
'z', 'x', 'c', 'v', 'b', 'n', 'm':
Writeln('This is in the fourth row in keyboard');
else
Writeln('Unknown letter');
end;
Write('Press enter key to close');
Readln;
end.

Note that we have used a new technique in the case condition, which is a set of values:
'z', 'x', 'c', 'v', 'b', 'n', 'm': which means execute case branch statement if the Key was one of
these values set: z, x, c, v, b, n or m We can also mix ranges with values set like this:
'a' .. 'd', 'x', 'y', 'z': which means execute the statement if the value falls between a and d, or
equal to x, y or z.

Loops
Loops are used to execute certain parts of code (statements) for a specific number of
times, or until a condition is satisfied.

For loop
You can execute for statements for a specific number of cycles using a counter like this
example:

Compiled by Engineer Mulimbi Bricious 18


var
i: Integer;
Count: Integer;
begin
Write('How many times? ');
Readln(Count);
for i:= 1 to Count do
Writeln('Hello there');
Write('Press enter key to close');
Readln;
end.

We should use ordinal types like Integer, Byte, and Char in for loop variables. We call this
variable a loop variable or loop counter. The value of loop counter can be initialized with
any number, and we can also determine the last value of loop counter. For example, if
we need to count from 5 to 10, then we can do this:
for i:= 5 to 10 do
We can display loop counter in every cycle of the loop, as in the modified example below:

var
i: Integer;
Count: Integer;
begin
Write('How many times? ');
Readln(Count);
for i:= 1 to Count do
begin
Writeln('Cycle number: ', i);
Writeln('Hello there');
end;
Write('Press enter key to close');
Readln;
end.

Note that this time we need to repeat two statements, and for that reason we have used
the begin . . end keywords to make them one statement.

Multiplication Table using for loop


The for-loop version of the Multiplication Table program is easier and more concise:

program MultTableWithForLoop;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
var
x, i: Integer;

Compiled by Engineer Mulimbi Bricious 19


begin
Write('Please input any number: ');
Readln(x);
for i:= 1 to 12 do
Writeln(x, ' * ', i, ' = ', x * i);
Writeln('Press enter key to close');
Readln;
end.

Instead of writing the Writeln statement 12 times, we write it once inside a loop which is
executed 12 times. We can make the for loop statement iterate in a backward direction
using downto keyword instead of to keyword using this syntax: for i:= 12 downto 1 do

Factorial program
Factorial in mathematics is the multiplication of a number by each one of its predecessors down to the
number 1. For example, 3! = 3 * 2 * 1 = 6.

var
Fac, Num, i: Integer;
begin
Write('Please input any number: ');
Readln(Num);
Fac:= 1;
for i:= Num downto 1 do
Fac:= Fac * i;
Writeln('Factorial of ', Num ,' is ', Fac);
Writeln('Press enter key to close');
Readln;
end.

Repeat Until loop


Unlike the for loop which repeats for a specific number of cycles, the Repeat loop has no
counter. It loops until a certain condition occurs (Returns True), then it will go to the next
statement after the loop. Example:

var
Num : Integer;
begin
repeat
Write('Please input a number: ');
Readln(Num);
until Num <= 0;
Writeln('Finished, please press enter key to close');
Readln;
end.

In the previous example, the program enters the loop, then it asks the user to enter a
number. If the number is less than or equal to zero, it will exit the loop. If the entered
number is greater than zero, the loop will continue.

Compiled by Engineer Mulimbi Bricious 20


Restaurant program using Repeat loop
var
Selection: Char;
Price: Integer;
Total: Integer;
begin
Total:= 0;
repeat
Writeln('Welcome to Pascal Restaurant. Please select your order');
Writeln('1 - Chicken (10 Geneh)');
Writeln('2 - Fish (7 Geneh)');
Writeln('3 - Meat (8 Geneh)');
Writeln('4 – Salad (2 Geneh)');
Writeln('5 - Orange Juice (1 Geneh)');
Writeln('6 - Milk (1 Geneh)');
Writeln('X - nothing');
Writeln;
Write('Please enter your selection: ');
Readln(Selection);
case Selection of
'1': begin
Writeln('You have ordered Chicken, this will take 15 minutes');
Price:= 10;
end;
'2': begin
Writeln('You have ordered Fish, this will take 12 minutes');
Price:= 7;
end;
'3': begin
Writeln('You have ordered meat, this will take 18 minutes');
Price:= 8;
end;
'4': begin
Writeln('You have ordered Salad, this will take 5 minutes');
Price:= 2;
end;
'5': begin
Writeln('You have ordered Orange juice, this will take 2 minutes');
Price:= 1;
end;
'6': begin
Writeln('You have ordered Milk, this will take 1 minute');
Price:= 1;
end;
else
begin
Writeln('Wrong entry');
Price:= 0;
end;
end;
Total:= Total + Price;
until (Selection = 'x') or (Selection = 'X');
Writeln('Total price = ', Total);
Write('Press enter key to close');

Compiled by Engineer Mulimbi Bricious 21


Readln;
end.

In the previous example, we used these techniques:


1. Adding begin end in case branches to convert multiple statements to one statement
2. We initialized (put a starting value in a variable) the variable Total to zero, to
accumulate the total price of orders. Then we added the selected price in every loop
to the Total variable: Total:= Total + Price;
3. We put two options to finish the orders, either capital X, or small x. Both characters
are different in representation (storage) in computer memory.

Note:
We could replace this line:
until (Selection = 'x') or (Selection = 'X');
By this abbreviated code:
until UpCase(Selection) = 'X';
This will change the Selection variable to upper case if it is a lowercase letter, and the
condition will return True in both cases (x or X)

While loop
The while loop is similar to the repeat loop, but it differs from it in these aspects:
1. In the while , the condition is checked first before entering the loop, but repeat enters
the loop first then it checks the condition. That means repeat always executes its
statement(s) once at least, but while loop could prevent entering the first cycle if the
condition returns False from the beginning.
2. while loop needs begin end if there are multiple statements that need to be executed
in a loop, but repeat does not need begin end, its block (repeated statements) starts
from the repeat keyword to the until keyword.

Example:

var
Num: Integer;
begin
Write('Input a number: ');
Readln(Num);
while Num > 0 do
begin
Write('From inside loop: Input a number : ');
Readln(Num);
end;
Write('Press enter key to close');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 22


Factorial program using while loop
var
Fac, Num, i: Integer;
begin
Write('Please input any number: ');
Readln(Num);
Fac:= 1;
i:= Num;
while i > 1 do
begin
Fac:= Fac * i;
i:= i - 1;
end;
Writeln('Factorial of ', Num ,' is ', Fac);
Writeln('Press enter key to close');
Readln;
end.

The while loop has no loop counter, and for that reason we have used the variable i to
work as a loopcounter. The loop counter value is initialized by the number for which we
need to get its factorial, then we decrease it manually in each cycle of the loop. When i
reaches 1, the loop will break.

Strings
The String type is used to declare variables that can hold a chain of characters. It can
be used to store text, a name, or a combination of characters and digits like a car
license plate number. In this example we will see how we can use the string variable to
accept a user name:

var
Name: string;
begin
Write('Please enter your name : ');
Readln(Name);
Writeln('Hello ', Name);
Writeln('Press enter key to close');
Readln;
end.

In the next example, we will use strings to store information about a person:

var
Name: string;
Address: string;
ID: string;
DOB: string;
begin
Write('Please enter your name : ');
Readln(Name);
Write('Please enter your address : ');

Compiled by Engineer Mulimbi Bricious 23


Readln(Address);
Write('Please enter your ID number : ');
Readln(ID);
Write('Please enter your date of birth : ');
Readln(DOB);
Writeln;
Writeln('Card:');
Writeln('------------------------------------------');
Writeln('| Name : ', Name);
Writeln('| Address : ', Address);
Writeln('| ID : ', ID);
Writeln('| DOB : ', DOB);
Writeln('------------------------------------------');
Writeln('Press enter key to close');
Readln;
end.

Strings can be concatenated to produce larger strings. For example we can concatenate
FirstName, SecondName, and FamilyName into another string called FullName, similar
to the next example:

var
YourName: string;
Father: string;
GrandFather: string;
FullName: string;
begin
Write('Please enter your first name : ');
Readln(YourName);
Write('Please enter your father name : ');
Readln(Father);
Write('Please enter your grand father name : ');
Readln(GrandFather);
FullName:= YourName + ' ' + Father + ' ' + GrandFather;
Writeln('Your full name is: ', FullName);
Writeln('Press enter key to close');
Readln;
end.

Note that in this example we have added a space (' ') between names (like YourName +
' ' + Father) tomake a separation between names. The space is a character too. We can
do many operations on strings, like searching for subtext in a string, copying one string
to another string variable, or converting text characters to capital or lowercase like the
examples below: This line converts the letters in the FullName string value to capital
letters: FullName:= UpperCase(FullName); And this converts it to lowercase letters: FullName:=
LowerCase(FullName); In the next example, we need to search for the letter a in a user name
using the Pos function. The Pos function returns the first occurrence (Index) of that
character in a string, or returns zero if that letter or substring does not exist in the searched
text:

Compiled by Engineer Mulimbi Bricious 24


var
YourName: string;
begin
Write('Please enter your name : ');
Readln(YourName);
If Pos('a', YourName) > 0 then
Writeln('Your name contains a')
else
Writeln('Your name does not contain a letter');
Writeln('Press enter key to close');
Readln;
end.

If the name contains a capital A, then Pos function will not point to it, because A is different
from a as we mentioned earlier. To solve this problem we can convert all user name
letters to lowercase case, and then we can do the search: If Pos('a', LowerCase(YourName))
> 0 the In the next modification of the code, we will display the position of the letter a in a
user name:

var
YourName: string;
begin
Write('Please enter your name : ');
Readln(YourName);
If Pos('a', LowerCase(YourName)) > 0 then
begin
Writeln('Your name contains a');
Writeln('a position in your name is: ',
Pos('a', LowerCase(YourName)));
end
else
Writeln('Your name does not contain a letter');
Write('Press enter key to close');
Readln;
end.

You may notice that if the name contains more than one letter a , the function Pos will
return the index of the first occurrence of the letter a in the user name. You can get the
count of characters in a string using the function Length: Writeln('Your name length is ',
Length(YourName), ' letters'); And you can get the first letter/character of a string using its
index number: Writeln('Your first letter is ', YourName[1]); And the second character: Writeln('Your
second letter is ', YourName[2]); The last character: Writeln('Your last letter is ',
YourName[Length(YourName)]); You can also display a string variable character by character
using a for loop: for i:= 1 to Length(YourName) do Writeln(YourName[i]);

Copy function
We can copy part of a string using the function copy. For example, if we need to extract
the word 'world' from the string 'hello world', we can do it if we know the position of that
part, as we have done in the example below:

Compiled by Engineer Mulimbi Bricious 25


var
Line: string;
Part: string;
begin
Line:= 'Hello world';
Part:= Copy(Line, 7, 5);
Writeln(Part);
Writeln('Press enter key to close');
Readln;
end.

Note that we have used the Copy function using this syntax:
Part:= Copy(Line, 7, 5);
Here is an explanation of above statement:
• Part:= This is the string variable in which we will put the function result (sub string,
'world').
• Line This is the source string which contains the 'Hello world' sentence.
• 7 This is the starting point or index of sub string that we need to extract, in this
case it is the character w.
• 5 This is the length of the extracted part. In this case it represents the length of the
word 'world'.

In the next example, we will ask the user to enter a month name, like February, then the
program will type the short version of it, like Feb:

var
Month: string;
ShortName: string;
begin
Write('Please input full month name e.g. January : ');
Readln(Month);
ShortName:= Copy(Month, 1, 3);
Writeln(Month, ' is abbreviated as : ', ShortName);
Writeln('Press enter key to close');
Readln;
end.

Insert procedure
The Insert procedure inserts a substring into a string. Unlike the string concatenation
operator (+) which links two substrings together, Insert adds the substring in the middle
of another string. For example, we can insert the word Pascal into the string 'Hello world',
resulting in 'Hello Pascal World' as in the following example:

var
Line: string;
begin
Line:= 'Hello world';
Insert('Pascal ', Line, 7);
Writeln(Line);
Writeln('Press enter key to close');
Readln;

Compiled by Engineer Mulimbi Bricious 26


end.

Parameters of the Insert procedure are:


• 'Pascal' This is the substring that we need to insert inside the destination string.
• Line This is the destination string that will contain the result of the operation.
• 7 This is the position to start the insertion in the destination string. In this case it
will be after the seventh character, which is the first space of 'Hello world'.

Delete procedure
This procedure is used to delete a character or substring from a string. We need to know
the start position and the length of substring that should be deleted. For example, if we
need to delete the letters ll from the string 'Hello World' to make 'Heo World', we
can do it like this:

var
Line: string;
begin
Line:= 'Hello world';
Delete(Line, 3, 2);
Writeln(Line);
Writeln('Press enter key to close');
Readln;
end.

Trim function
This function is used to remove spaces from the start and the end of strings. If we have
a string that contains the text ' Hello ' it will be 'Hello' after using this function. We can not
display spaces in a terminal window unless we put characters between them. Look at the
example below:

program TrimStr;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
Line: string;
begin
Line:= ' Hello ';
Writeln('<', Line, '>');
Line:= Trim(Line);
Writeln('<', Line, '>');
Writeln('Press enter key to close');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 27


In the foregoing example, we have used the unit SysUtils, which contains the Trim
function. There are another two functions that remove spaces from only one side of a
string, before/after. These functions are: TrimRight, TrimLeft.

StringReplace function
The StringReplace function replaces characters or substrings with other characters or
substrings in the desired string.

program SٍtrReplace;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
Line: string;
Line2: string;
begin
Line:= 'This is a test for string replacement';
Line2:= StringReplace(Line, ' ', '-', [rfReplaceAll]);
Writeln(Line);
Writeln(Line2);
Write('Press enter key to close');
Readln;
end.

The parameters of the StringReplace function are:


1. Line: This is the original string that we need to modify.
2. ' ': This is the substring that we need to replace. It is space in this example.
3. '': This is the alternative substring that we want to replace the previous one in
original string.
4. [rfReplaceAll]: This is the replacement type. In this case we need to replace all
occurrence of the space substring.
We can use only one string variable and discard the variable Line2 as modified example
shows, but we will lose the original text value.

var
Line: string;
begin
Line:= 'This is a test for string replacement';
Writeln(Line);
Line:= StringReplace(Line, ' ', '-', [rfReplaceAll]);
Writeln(Line);
Write('Press enter key to close');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 28


Arrays
An Array is a chain of variables of the same type. If we need to declare an array of 10
Integer variables, we can do it like this: Numbers: array [1 .. 10] of Integer; We can access
single variables in the array using its index. For example, to put a value in the first variable
in the array we can write it as: Numbers[1]:= 30; To put a value in the second variable, use
the index 2: Numbers[2]:= 315; In the next example, we will ask the user to enter 10 student
marks and put them in an array. Eventually we will go through them to extract pass/fail
results:

var
Marks: array [1 .. 10] of Integer;
i: Integer;
begin
for i:= 1 to 10 do
begin
Write('Input student number ', i, ' mark: ');
Readln(Marks[i]);
end;
for i:= 1 to 10 do
begin
Write('Student number ', i, ' mark is : ', Marks[i]);
if Marks[i] >= 40 then
Writeln(' Pass')
else
Writeln(' Fail');
end;
Writeln('Press enter key to close');
Readln;
end.
We can modify the previous code to get the highest and lowest student marks:
var
Marks: array [1 .. 10] of Integer;
i: Integer;
Max, Min: Integer;
begin
for i:= 1 to 10 do
begin
Write('Input student number ', i, ' mark: ');
Readln(Marks[i]);
end;
Max:= Marks[1];
Min:= Marks[1];
for i:= 1 to 10 do
begin
// Check if current Mark is maximum mark or not
if Marks[i] > Max then
Max:= Marks[i];
// Check if current value is minimum mark or not
if Marks[i] < Min then
Min:= Marks[i];
Write('Student number ', i, ' mark is : ', Marks[i]);
if Marks[i] >= 40 then
Writeln(' Pass')

Compiled by Engineer Mulimbi Bricious 29


else
Writeln(' Fail');
end;
Writeln('Max mark is: ', Max);
Writeln('Min mark is: ', Min);
Writeln('Press enter key to close');
Readln;
end.

Note that we consider the first mark (Marks[1]) as the maximum and minimum mark, and
then we will compare it with the rest of the marks. Max:= Marks[1]; Min:= Marks[1]; Inside the
loop we compare Max, Min with each mark. If we find a number that is larger than Max,
we will replace Max value with it. If we find a number that is less than Min, then we will
replace Min with it. In the previous example we have introduced comments:
// Check if current Mark is maximum mark or not
We have started the line with the characters //, which means that this line is a comment
and will not affect the code and will not be compiled. This technique is used to describe
parts of code to other programmers or to the programmer himself/herself. // is used for
short comments. If we need to write multiline comments we can surround them by {} or
(**)
Example:
for i:= 1 to 10 do
begin
{ Check if current Mark is maximum mark or not
check if Mark is greater than Max then put
it in Max }
if Marks[i] > Max then
Max:= Marks[i];
(* Check if current value is minimum mark or not
if Min is less than Mark then put Mark value in Min
*)
if Marks[i] < Min then
Min:= Marks[i];
Write('Student number ', i, ' mark is : ', Marks[i]);
if Marks[i] >= 40 then
Writeln(' Pass')
else
Writeln(' Fail');
end;
We can also disable part of our code temporarily by commenting it:
Writeln('Max mark is: ', Max);
// Writeln('Min mark is: ', Min);
Writeln('Press enter key to close');
Readln;
In the above code, we have disabled the procedure for writing the minimum student mark.
Note:
We can declare an array as having a zero based index the same as in the C language:
Marks: array [0 .. 9] of Integer;
This can hold 10 elements too, but the first item can be accessed using the index 0:
Numbers[0]:= 30;
Second item:
Numbers[1]:= 315;

Compiled by Engineer Mulimbi Bricious 30


Last item:
Numbers[9]:= 10;
or
Numbers[High(Numbers)]:= 10;

Records
While arrays can hold many variables of the same type, records can hold variables of
different types, and these variables are called 'Fields'. This group of variables/fields can
be treated as a single unit or variable. We can use records to store information that belong
to the same object, for example, car information:
1. Car type: string variable
2. Engine size: real number
3. Production year: integer value
We can collect these different types in one record which represents a Car as in the
following example:

program Cars;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
type
TCar = record
ModelName: string;
Engine: Single;
ModelYear: Integer;
end;
var
Car: TCar;
begin
Write('Input car Model Name: ');
Readln(Car.ModelName);
Write('Input car Engine size: ');
Readln(Car.Engine);
Write('Input car Model year: ');
Readln(Car.ModelYear);
Writeln;
Writeln('Car information: ');
Writeln('Model Name : ', Car.ModelName);
Writeln('Engine size : ', Car.Engine);
Writeln('Model Year : ', Car.ModelYear);
Write('Press enter key to close..');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 31


In this example, we have defined a new type (Record) using the 'type' keyword: type
TCar = record
ModelName: string;
Engine: Single;
ModelYear: Integer;
end;

We have added the letter (T) to Car to indicate that this is a type and not a variable.
Variable names could be like: Car, Hour, UserName, but type names should be like: TCar,
THouse, and TUserName. This is a standard in the Pascal language. When we need to
use this new type, then we should declare a variable of that type, for example:
var
Car: TCar;
If we need to store a value in one of its variables/fields, we should access it like this:
Car.ModelName
Records will be used in the Random access files section of this book.

Files
Files are important elements of operating systems and applications. Operating system
components are represented as files, and information and data are represented in files
too, like photos, books, applications, and simple text files. Operating systems control files
management like: reading, writing, editing and deleting files. Files are divided into many
types according to many perspectives. We can group files into two types: executable files,
and data files. For example compiled binary Lazarus applications are executable files,
while Pascal source code (.pas) are data files. Also PDF books, JPEG pictures, are data
files. We can divide data files into two types according to the representation of their
contents:
1. Text files: which are simple text files that can be written, or read using any simple
tool including operating system command lines like cat, vi commands in Linux and
type, copy con commands in Windows.
2. Binary data files: These are more complex and need special applications to open
them. For example, picture files cannot be opened using simple command line
tools, instead they should be opened using applications like GIMP, Kolour Paint,
MS Paint, etc. If we open picture, or voice files, we will get unrecognizable
characters which mean nothing to the user. Examples of binary data files are
database files, which should be opened using the proper application. There is
another way to categorize files according to access type:
1. Sequential access files: An example of a sequential file is a text file, which has no
fixed size record. Each line has its own length, so we can't know the position (in
characters) for the start of the third line for example. For that reason, we could
open the file for read only, or writing only, and we can also append text only to the
end of file. If we need to insert text in the middle of a file, then we should read file
contents into memory, do the modifications, erase the entire file from disk, then
overwrite it the file with the modified text.
2. Random access files: This type of file has a fixed size record. A record is the
smallest unit that we can read and write at one time, and it could be Byte, Integer,

Compiled by Engineer Mulimbi Bricious 32


string, or a user defined record. We can read and write at the same time, for
example, we could read the record number 3 and copy it to the record number 10.
In this case, we can know exactly the position of each record in the file. Modifying
records is simple. In random access files, we can replace/overwrite any record
without affecting the rest of the file.

Text files
Text files are the simplest files, but we should write to them in only one direction (only
forward). We cannot go back while writing to a text file. We should also define the
operation mode before opening the file: Read, Write or Append (writing at the end). In this
example, we will display the contents of a text file selected by a user. For example, a user
may have a text file name like c:\test\first.pas in Windows or /home/user/first.pas in Linux:

Reading text file program


program ReadFile;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, sysUtils
{ you can add units after this };
var
FileName: string;
F: TextFile;
Line: string;
begin
Write('Input a text file name: ');
Readln(FileName);
if FileExists(FileName) then
begin
// Link file variable (F) with physical file (FileName)
AssignFile(F, FileName);
Reset(F); // Put file mode for read, file should exist
// while file has more lines that does not read yet do the loop
while not Eof(F) do
begin
Readln(F, Line); // Read a line from text file
Writeln(Line); // Display this line in user screen
end;
CloseFile(F); // Release F and FileName connection
end
else // else if FileExists..
Writeln('File does not exist');
Write('Press enter key to close..');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 33


In Linux we can enter these file names: /etc/resolv.conf or /proc/meminfo /proc/cpuinfo
We have used new types, functions and procedures to manipulate text files which are:
1. F: TextFile; TextFile is a type that is used to declare a text file variable. This
variable can be linked to a text file for later usage.
2. if FileExists(FileName) then FileExists is a function contained in the SysUtils unit. It
checks for a file's existence. It returns True if the file exists in the storage media.
3. AssignFile(F, FileName); After we have checked for the file's existence, we can use
the AssignFile procedure to link the file variable (F) with the physical file. Any
further usage of F variable will represent the physical file.
4. Reset(F); // Put file mode for read, file should exist The Reset procedure opens text
files for reading only, and puts the reading pointer at the first character of the file.
If there is no read permission for that file for the current user, an error message
will appear, like access denied.
5. Readln(F, Line); // Read a line from text file The procedure Readln is used to read a
complete line from the file and put it in the variable Line. Before reading a line
from text file, we should make sure that the file has not reached the end. We can
do that with the next function, Eof.
6. while not Eof(F) do The Eof function returns True if the file has reached its end. It is
used to indicate that the Read operation couldn't be used anymore and we have
read all of the file's contents.
7. CloseFile(F); // Release F and FileName connection After finishing reading from or writing
to a file, we should close it to release the file, because the Reset procedure
reserves the file in the operating system and prevents writing and deletion by
another application while the file is open. We should use CloseFile only when the
Reset procedure succeeds in opening the file. If Reset fails (for example, if the
file does not exist, or is being used by another application) in that case we should
not close the file. In the next example we will create a new text file and put some
text in it:

Creating and writing into text file


var
FileName: string;
F: TextFile;
Line: string;
ReadyToCreate: Boolean;
Ans: Char;
i: Integer;
begin
Write('Input a new file name: ');
Readln(FileName);
// Check if file exists, warn user if it is already exist
if FileExists(FileName) then
begin
Write('File already exist, did you want to overwrite it? (y/n)');
Readln(Ans);
if upcase(Ans) = 'Y' then
ReadyToCreate:= True

Compiled by Engineer Mulimbi Bricious 34


else
ReadyToCreate:= False;
end
else // File does not exist
ReadyToCreate:= True;
if ReadyToCreate then
begin
// Link file variable (F) with physical file (FileName)
AssignFile(F, FileName);
Rewrite(F); // Create new file for writing
Writeln('Please input file contents line by line, '
, 'when you finish write % then press enter');
i:= 1;
repeat
Write('Line # ', i, ':');
Inc(i);
Readln(Line);
if Line <> '%' then
Writeln(F, Line); // Write line into text file
until Line = '%';
CloseFile(F); // Release F and FileName connection, flush buffer
end
else // file already exist and user does not want to overwrite it
Writeln('Doing nothing');
Write('Press enter key to close..');
Readln;
end.

In this example, we have used many important things:


1. Boolean type: ReadyToCreate: Boolean; This type can hold only one of two values:
either True or False. These values can be used directly in if condition, while loop
or repeat loop. In the previous example, we have used the if condition like this: if
Marks[i] > Max then Which eventually turns to True or False.
2. UpCase function: if upcase(Ans) = 'Y' then This statement is executed when the file
exists. The program will warn the user about overwriting an existing file. If he/she
wants to continue, then he/she should enter a lowercase y or capital Y. The
UpCase function will convert the character into a capital letter if it is lowercase.
3. Rewrite procedure: Rewrite(F); // Create new file for writing The Rewrite procedure is
used to create a new empty file. If the file already exists, it will be erased and
overwritten. It also opens the file for writing only in case of text files.
4. Writeln(F, ..) procedure: Writeln(F, Line); // Write line into text file This procedure is used
to write string or variables in text file, and appends them with end of line characters,
which are a carriage return/line feed combination (CR/LF), represented as the
characters for the numbers 13 and 10 respectively. These characters can not be
displayed in a console window, but it will move the screen display cursor to a new
line.
5. Inc procedure: Inc(i); This procedure increases an integer variable by one. It is
equivalent to the statement: i:= i + 1;
6. CloseFile procedure: CloseFile(F); // Release F and FileName connection, flush buffer As we
mentioned earlier, the CloseFile procedure releases a file in the operating system.

Compiled by Engineer Mulimbi Bricious 35


In addition, it has an additional job when writing to a text file, which is flushing the
writing buffer.
Buffering of text files is a feature that makes dealing with text files faster. Instead of writing
a single line or character directly to disk or any other storage media (which is very slow
compared with writing into memory), the application will write these entries into a memory
buffer. When the buffer reaches its full size, it will be flushed (forced to be written) into
permanent storage media like a hard disk. This operation makes writing faster, but it will
add the risk of losing some data (in the buffer) if the power is suddenly lost. To minimize
data loss, we should close the file immediately after finishing writing to it, or calling the
Flush procedure to flush the buffer explicitly.

Appending to a text file


In this example, we want to open an existing text file for writing at the end of it, without
removing its original contents using the procedure Append.

Add to text file program


var
FileName: string;
F: TextFile;
Line: string;
i: Integer;
begin
Write('Input an existed file name: ');
Readln(FileName);
if FileExists(FileName) then
begin
// Link file variable (F) with physical file (FileName)
AssignFile(F, FileName);
Append(F); // Open file for appending
Writeln('Please input file contents line by line',
'when you finish write % then press enter');
i:= 1;
repeat
Write('Line # ', i, ' append :');
Inc(i);
Readln(Line);
if Line <> '%' then
Writeln(F, Line); // Write line into text file
until Line = '%';
CloseFile(F); // Release F and FileName connection, flush buffer
end
else
Writeln('File does not exist');
Write('Press enter key to close..');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 36


After we run this application and enter an existing text file, we can view it with the cat /
type commands, or by double clicking on it in its directory to see the appended data.

Random access files


As we mentioned earlier, the second type of file according to an access type perspective
is Random access , or direct access. This type of file has a fixed size record, so that we
can jump to any record for reading or writing at any time. There are two types of random
access files: typed files and untyped files.

Typed files
Typed files are used for files that contain the same type of data that has the same size of
records, for example, if a file contains records of Byte type, that means the record size =
1 byte. If the file contains real numbers (Single), that means all record sizes are 4 bytes,
etc. In the next example, we will show how to use file of Byte:

Marks program
var
F: file of Byte;
Mark: Byte;
begin
AssignFile(F, 'marks.dat');
Rewrite(F); // Create file
Writeln('Please input students marks, write 0 to exit');
repeat
Write('Input a mark: ');
Readln(Mark);
if Mark <> 0 then // Don't write 0 value
Write(F, Mark);
until Mark = 0;
CloseFile(F);
Write('Press enter key to close..');
Readln;
end.

In this example, we have used this syntax to define a typed file:


F: file of Byte;
Which means: the file contains records of Byte data type, which can hold values from 0
to 255.
And we have created the file and opened it for writing using the Rewrite procedure:
Rewrite(F); // Create file
Also we have used the function Write instead of Writeln to write records in the typed file:
Write(F, Mark);
Writeln is not suitable for typed files, because it appends CR/LF characters on each line
of written text, but Write stores the record as it is without any additions. In this case, if we
have entered 10 records (of Byte), file size will be 10 bytes on disk.

Compiled by Engineer Mulimbi Bricious 37


In the next example, we will show how to display the previous file's contents:

Reading student marks


program ReadMarks;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
F: file of Byte;
Mark: Byte;
begin
AssignFile(F, 'marks.dat');
if FileExists('marks.dat') then
begin
Reset(F); // Open file
while not Eof(F) do
begin
Read(F, Mark);
Writeln('Mark: ', Mark);
end;
CloseFile(F);
end
else
Writeln('File (marks.dat) not found');
Write('Press enter key to close..');
Readln;
end.

In the next example, we will show how to append new records without deleting the existing
data:

Appending student marks program


program AppendMarks;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
F: file of Byte;
Mark: Byte;
begin
AssignFile(F, 'marks.dat');

Compiled by Engineer Mulimbi Bricious 38


if FileExists('marks.dat') then
begin
FileMode:= 2; // Open file for read/write
Reset(F); // open file
Seek(F, FileSize(F)); // Go to beyond last record
Writeln('Please input students marks, write 0 to exit');
repeat
Write('Input a mark: ');
Readln(Mark);
if Mark <> 0 then // Don't write 0 value in disk
Write(F, Mark);
until Mark = 0;
CloseFile(F);
end
else
Writeln('File marks.dat not found');
Write('Press enter key to close..');
Readln;
end.

After running this program and entering new records, we can run it again to see the
appended data. Note that we have used Reset for opening the file for writing instead of
the Rewrite procedure. Rewrite erases all data for existing files, and creates an empty file
if the file does not exist, while Reset can only open an existing file without erasing its
contents.
Also, we have assigned 2 to the FileMode variable to indicate that we need to open the
file for read/write access mode. 0 in FileMode means read only, 1 means write only, 2
(Default) means read/write. FileMode:= 2; // Open file for read/write
Reset(F); // open file Reset puts the read/write pointer to the first record, and for that reason
if we start to write records immediately, we will overwrite the old records, so we have used
the Seek procedure to move the read/write pointer to the end of file. Seek can be used
only with random access files. If we try to access a record position that does not exist with
the Seek procedure (for example, record number 100, while we have only 50 records),
we will get an error. We have also used the FileSize function, which returns the current
record count in the file. It is used in combination with the Seek procedure to jump to the
end of the file: Seek(F, FileSize(F)); // Go to after last record Note that this example can be used
if the Student marks file already exists; if not, then we should run the first program (Storing
Student Marks) because it uses Rewrite which can create new files. We can combine
both methods (Reset and Rewrite) according to whether the file exists, as we have done
in the next example:

Create and append student marks program


program ReadWriteMarks;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}

Compiled by Engineer Mulimbi Bricious 39


Classes, SysUtils
{ you can add units after this };
var
F: file of Byte;
Mark: Byte;
begin
AssignFile(F, 'marks.dat');
if FileExists('marks.dat') then
begin
FileMode:= 2; // Open file for read/write
Reset(F); // open file
Writeln('File already exist, opened for append');
// Display file records
while not Eof(F) do
begin
Read(F, Mark);
Writeln('Mark: ', Mark);
end
end
else // File not found, create it
begin
Rewrite(F);
Writeln('File does not exist,, not it is created');
end;
Writeln('Please input students marks, write 0 to exit');
Writeln('File pointer position at record # ', FilePos(f));
repeat
Write('Input a mark: ');
Readln(Mark);
if Mark <> 0 then // Don't write 0 value
Write(F, Mark);
until Mark = 0;
CloseFile(F);
Write('Press enter key to close..');
Readln;
end.

Note that in this example, we didn't use the Seek procedure, instead we read all file
contents first. This operation (Read all file) moves the pointer to the end of file. In the next
example, we will use a file of records to store Cars information.

Cars database program


program CarRecords;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
type
TCar = record

Compiled by Engineer Mulimbi Bricious 40


ModelName: string[20];
Engine: Single;
ModelYear: Integer;
end;
var
F: file of TCar;
Car: TCar;
begin
AssignFile(F, 'cars.dat');
if FileExists('cars.dat') then
begin
FileMode:= 2; // Open file for read/write
Reset(F); // open file
Writeln('File already exist, opened for append');
// Display file records
while not Eof(F) do
begin
Read(F, Car);
Writeln;
Writeln('Car # ', FilePos(F), ' --------------------------');
Writeln('Model : ', Car.ModelName);
Writeln('Year : ', Car.ModelYear);
Writeln('Engine: ', Car.Engine);
end
end
else // File not found, create it
begin
Rewrite(F);
Writeln('File does not exist, created');
end;
Writeln('Please input car informaion, ',
'write x in model name to exit');
Writeln('File pointer position at record # ', FilePos(f));
repeat
Writeln('--------------------------');
Write('Input car Model Name : ');
Readln(car.ModelName);
if Car.ModelName <> 'x' then
begin
Write('Input car Model Year : ');
Readln(car.ModelYear);
Write('Input car Engine size: ');
Readln(car.Engine);
Write(F, Car);
end;
until Car.ModelName = 'x';
CloseFile(F);
Write('Press enter key to close..');
Readln;
end.

In the previous example, we declared TCar type to define car information. The first field
(ModelName) is a string variable, but we limited its maximum length [20]: ModelName:
string[20];

Compiled by Engineer Mulimbi Bricious 41


We should use this declaration for string variables before we use them in files, because
the default ANSI String variables has a different and unlimited storage type in memory,
but for typed files, every data type width should be defined.

File copying
All file types, like text files, binary files, are based on byte units, which are the smallest
representation of data in computer memory and on disk. Every file should contain one
byte, two bytes, etc, or no bytes at all. Every byte could hold an integer or a character
code from 0 to 255. We can open all file types using the File of Byte or File of Char
declaration. We can copy any file to another one using File of Byte files, and the result
will be a new file that is identical to the source file's contents.

Copy files using file of byte


program FilesCopy;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
SourceName, DestName: string;
SourceF, DestF: file of Byte;
Block: Byte;
begin
Writeln('Files copy');
Write('Input source file name: ');
Readln(SourceName);
Write('Input destination file name: ');
Readln(DestName);
if FileExists(SourceName) then
begin
AssignFile(SourceF, SourceName);
AssignFile(DestF, DestName);
FileMode:= 0; // open for read only
Reset(SourceF); // open source file
Rewrite(DestF); // Create destination file
// Start copy
Writeln('Copying..');
while not Eof(SourceF) do
begin
Read(SourceF, Block); // Read Byte from source file
Write(DestF, Block); // Write this byte into new
// destination file
end;
CloseFile(SourceF);
CloseFile(DestF);
end

Compiled by Engineer Mulimbi Bricious 42


else // Source File not found
Writeln('Source File does not exist');
Write('Copy file is finished, press enter key to close..');
Readln;
end.

After running the previous example, we should enter an existing source file and a new
destination file. In Linux we could enter file names like this: Input source file name:
/home/motaz/quran/mishari/32.mp3 Input destination file name:
/home/motaz/Alsajda.mp3 In Windows we could enter something like this: Input source
file name: c:\photos\mypphoto.jpg Input destination file name: c:\temp\copy.jpg If the
source file exists in the same directory as the FileCopy program, we could enter only the
file name like this: Input source file name: test.pas Input destination file name:
testcopy.pas If we use this method to copy large files, it will take a very long time
compared with operating system copy procedures. That means the operating system
uses a different technique to copy files. If we want to copy a 1 megabyte file, that means
the while loop will repeat about 1 million times, that means a million read and a million
write operations. If we replace the file of Byte declaration with file of Word, that means it
will take about 500,000 cycles for read and write, but this will work only for the files whose
size is even not odd. It will succeed if a file contains 1,420 bytes, but it will fail with a file
of 1,423 bytes. To copy a file of any kind using a faster method, we should use untyped
files.

Untyped files
Untyped files are random access files,that have a fixed record length, but are not linked
to any data type. Instead, they treat data (records) as an array of bytes or characters.

Copy files using untyped files program


program FilesCopy2;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
SourceName, DestName: string;
SourceF, DestF: file;
Block: array [0 .. 1023] of Byte;
NumRead: Integer;
begin
Writeln('Files copy');
Write('Input source file name: ');
Readln(SourceName);
Write('Input destination file name: ');
Readln(DestName);

Compiled by Engineer Mulimbi Bricious 43


if FileExists(SourceName) then
begin
AssignFile(SourceF, SourceName);
AssignFile(DestF, DestName);
FileMode:= 0; // open for read only
Reset(SourceF, 1); // open source file
Rewrite(DestF, 1); // Create destination file
// Start copy
Writeln('Copying..');
while not Eof(SourceF) do
begin
// Read Byte from source file
BlockRead(SourceF, Block, SizeOf(Block), NumRead);
// Write this byte into new destination file
BlockWrite(DestF, Block, NumRead);
end;
CloseFile(SourceF);
CloseFile(DestF);
end
else // Source File not found
Writeln('Source File does not exist');
Write('Copy file is finished, press enter key to close..');
Readln;
end.

New things in the previous example are:


1. Declaration type of files: SourceF, DestF: file;
2. Read/write variable (Buffer) Block: array [0 .. 1023] of Byte; We have used an array of bytes
(1 Kilo bytes, and it can be modified) to read and copy files blocks.
3. Opening an untyped file requires an additional parameter: Reset(SourceF, 1); // open
source file Rewrite(DestF, 1); // Create destination file The additional parameter is the record
size, which is the minimum element that can be read/written at a time. Since we need
to copy any file type, that means it should be one byte, because it can be used with
any file size.
4. Read procedure: BlockRead(SourceF, Block, SizeOf(Block), NumRead); The BlockRead
procedure is used with untyped files. It reads a bunch of data at a time. The
parameters of the BlockRead procedure are:
• SourceF: This is the source file variable that we need to copy.
• Block : This is the variable or array that will store the current data being read and
written.
• SizeOf(Block): This is the desired number of records that we need to read at one
time. For example ,if we enter 100 that means we need to read 100 records (bytes
on this case). If we use the SizeOf function, that means we need to read records
typical to the number of the container (Array of Bytes).
• NumRead: We have told the BlockRead function to read a specific number of
records (1024), and some times it succeeds in reading all of that amount, and
sometimes it gets only part of it. For example, suppose that we need to read a file
that contains only 100 bytes, that means BlockRead could read only 100 bytes.
Reading fewer records than desired happens also at the last block of the file. If the
file contains 1034 bytes for example, that means in the first loop, we will get 1024,

Compiled by Engineer Mulimbi Bricious 44


but in next loop we will get only 10 bytes left, and Eof function will return True. We
need the NumRead value to use with the BlockWrite procedure.
5. Writing to untyped files: BlockWrite(DestF, Block, NumRead); This is the write procedure,
and it is similar to the BlockRead procedure, but it has some differences: 1. Instead of
using the SizeOf procedure, we have used NumRead, because NumRead contains
the actual read Block size. 2. The fourth parameter NumWritten (which is not used in
this example) is not important, because we always get records written as we desire,
unless the disk is full. After we run this application, notice the speed of copying large
files. If the file contains 1 Megabytes, that means we need only about one thousand
reading/writing cycles to copy the entire file. In the next example, we will use untyped
files to read any file and display it as it is stored in memory or on disk. As we know,
files are list of bytes.

Display file contents program


program ReadContents;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
FileName: string;
F: file;
Block: array [0 .. 1023] of Byte;
i, NumRead: Integer;
begin
Write('Input source file name: ');
Readln(FileName);
if FileExists(FileName) then
begin
AssignFile(F, FileName);
FileMode:= 0; // open for read only
Reset(F, 1);
while not Eof(F) do
begin
BlockRead(F, Block, SizeOf(Block), NumRead);
// display contents in screen
for i:= 0 to NumRead - 1 do
Writeln(Block[i], ':', Chr(Block[i]));
end;
CloseFile(F);
end
else // File does not exist
Writeln('Source File does not exist');
Write('press enter key to close..');
Readln;
end.

Compiled by Engineer Mulimbi Bricious 45


After running this example and entering a text file name for example, we will see for the
first time CR/LF values (13/10), because we display each character code (ASCII). In Linux
we will find only line feed (LF) which has a value of 10 in decimal. This is a line delimiter
in text files. We can display other types of files, like pictures, executables, to see how they
look from the inside. We have used the Chr function in this example to get the numerical
value of characters, for example the letter a is stored in memory in a byte as 97, and
capital A is stored as 65.

Date and Time


Date and time are two of the most important issues in programming. It is important for the
applications that store transaction or any operation information, like purchasing, bills
payment, etc, they need to store the date and time of that transaction. Later they could
determine the transactions and operations that happened during the last month or current
month, for example. An applications log is one operation that relies on date/time
recording. We need to know when some application starts, stops, generates an error, or
crashes. TDateTime is the type in Object Pascal that we can use to store date/time
information. It is a double precision floating point number that occupies 8 bytes in memory.
The fractional part of this type represents time, and the integral part represents the
number of days that have passed since 30/Dec/1899. In the next example, we will show
how to display the current date/time value using the Now function.

program DateTime;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes , SysUtils
{ you can add units after this };
begin
Writeln('Current date and time: ', DateTimeToStr(Now));
Write('Press enter key to close');
Readln;
end.

We have used the DateTimeToStr function contained in the SysUtils unit to convert a
TDateTime type returned by the Now function to a readable date/time string
representation. If we do not use this conversion, we will get an encoded date/time
displayed as a real number: Writeln('Current date and time: ', Now); There are also two date/time
conversion functions that display the date part only and the time part only : Writeln('Current
date is ', DateToStr(Now)); Writeln('Current time is ', TimeToStr(Now)); The Date function returns
only the date part of today, and the Time function returns the current time only:
Writeln('Current date is ', DateToStr(Date)); Writeln('Current time is ', TimeToStr(Time)); These two
functions put zeroes in the other part, for example, the Date function returns the current
day and puts zero in the time part (Zero in time means 12:00 am). The Time function
returns the current system time, and puts zero in the date part (Zero in date means
30/12/1899). We can check this by using DateTimeToStr function:

Compiled by Engineer Mulimbi Bricious 46


Writeln('Current date is ', DateTimeToStr(Date));
Writeln('Current time is ', DateTimeToStr(Time));

The DateTimeToStr displays date/time according to the computer's date/time


configuration. Its result may vary between two computer systems, but the
FormatDateTime function will display date and time in the format written by the
programmer regardless of computer configuration: Writeln('Current date is ',
FormatDateTime('yyyy-mm-dd hh:nn:ss', Date)); Writeln('Current time is ', FormatDateTime('yyyy-mm-dd
hh:nn:ss', Time)); In the next example, we will treat date/time as a real number, and we will
add and subtract values from it:

begin
Writeln('Current date and time is ',
FormatDateTime('yyyy-mm-dd hh:nn:ss', Now));
Writeln('Yesterday time is ',
FormatDateTime('yyyy-mm-dd hh:nn:ss', Now - 1));
Writeln('Tomorrow time is ',
FormatDateTime('yyyy-mm-dd hh:nn:ss', Now + 1));
Writeln('Today + 12 hours is ',
FormatDateTime('yyyy-mm-dd hh:nn:ss', Now + 1/2));
Writeln('Today + 6 hours is ',
FormatDateTime('yyyy-mm-dd hh:nn:ss', Now + 1/4));
Write('Press enter key to close');
Readln;
end.

If we add one to or subtract one from a date, it will add/subtract a complete day. If we
add, for example,
½ or 0.5, this will add half a day (12 hours).
In the next example, we will generate a date value using a specific year, month and day:

var
ADate: TDateTime;
begin
ADate:= EncodeDate(1975, 11, 16);
Writeln('My date of birth is: ', FormatDateTime('yyyy-mm-dd', ADate));
Write('Press enter key to close');
Readln;
end.

The EncodeDate function accepts year, month and days as inputs, and returns
year/month/day values in one variable of type TDateTime. The EncodeTime function
accepts hour, minute, second and Milli second and returns time values as one TDateTime
value:

var
ATime: TDateTime;
begin
ATime:= EncodeTime(19, 22, 50, 0);
Writeln('Almughrib prayer time is: ', FormatDateTime('hh:nn:ss', ATime));
Write('Press enter key to close');
Readln;

Compiled by Engineer Mulimbi Bricious 47


end.

Date/time comparison
You can compare two date/time variables the same as comparing real numbers. For
example in real numbers: 9.3 is greater than 5.1, the same happens for TDateTime
values. Now + 1, which represents tomorrow, is greater than today (Now), and Now +
1/24 which means an hour after now is greater than Now – 2/24 which means two hours
before now. In the next example, we will put the date 1/Jan/2012 in a variable and
compare it with current date and check if this date is passed or not yet.

var
Year2012: TDateTime;
begin
Year2012:= EncodeDate(2012, 1, 1);
if Now < Year2012 then
Writeln('Year 2012 is not coming yet')
else
Writeln('Year 2012 is already passed');
Write('Press enter key to close');
Readln;
end.

We can add new functions to this example, which displays the remaining days or passed
days to/from that date:

var
Year2012: TDateTime;
Diff: Double;
begin
Year2012:= EncodeDate(2012, 1, 1);
Diff:= Abs(Now - Year2012);
if Now < Year2012 then
Writeln('Year 2012 is not coming yet, there are ',
Format('%0.2f', [Diff]), ' days Remaining ')
else
Writeln('First day of January 2012 is passed by ',
Format('%0.2f', [Diff]), ' Days');
Write('Press enter key to close');
Readln;
end.

Diff is a real number variable that will hold the difference between current date and the
2012 date. We also used the Abs function, which returns the absolute value of a number
(the number without the negative sign).

News recorder program


In this example, we will use text files to store News titles, and in addition, we will store
date and time too. After closing and opening the application again, it will display the
previously entered news titles with their date/time:

Compiled by Engineer Mulimbi Bricious 48


program news;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils
{ you can add units after this };
var
Title: string;
F: TextFile;
begin
AssignFile(F, 'news.txt');
if FileExists('news.txt') then
begin // Display old news
Reset(F);
while not Eof(F) do
begin
Readln(F, Title);
Writeln(Title);
end;
CloseFile(F); // reading is finished from old news
Append(F); // open file again for appending
end
else
Rewrite(F);
Write('Input current hour news title: ');
Readln(Title);
Writeln(F, DateTimeToStr(Now), ', ', Title);
CloseFile(F);
Write('Press enter to close');
Readln;
end.

Constants
Constants are similar to variables. They have names and can hold values, but differ from
variables in modifying that value. Constant values can not be modified while running the
application, and their values should be determined before compiling the application. We
have used constants in a different way before, without naming them, just as an Integer
value or string as in this example: Writeln(5); Writeln('Hello'); The value 5 will never change
after running the application. 'Hello' is also a string constant. We can define constants
using the Const keyword after the application's uses clause as in the following example:

Fuel Consumption program


program FuelConsumption;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}

Compiled by Engineer Mulimbi Bricious 49


Classes, SysUtils
{ you can add units after this };
const GallonPrice = 6.5;
var
Payment: Integer;
Consumption: Integer;
Kilos: Single;
begin
Write('How much did you pay for your car''s fuel: ');
Readln(Payment);
Write('What is the consumption of your car? (Kilos per Gallon): ');
Readln(Consumption);
Kilos:= (Payment / GallonPrice) * Consumption;
Writeln('This fuel will keep your car running for : ',
Format('%0.1f', [Kilos]), ' Kilometers');
Write('Press enter');
Readln;
end.

In the previous example, we will calculate the kilometers that the car could run with its
current fuel according to these facts:
1. Car fuel consumption: we have used the Consumption variable to store kilometers
per gallon for the current car
2. Fuel: we have used the Payment variable to store how much money we paid for
the current fuel
3. Gallon Price: we have used the GallonPrice constant to store the price for a gallon
of fuel for the current country. This value shouldn't be entered by the user; instead,
it should be defined by the programmer. Constants are recommended when using
the same value many times in the application. If we need to change this value, we
can do it once at the header of code.

Ordinal types
Ordinal types are integer values that use literal indications instead of numbers. For
example, if we need to define language variables (Arabic/English/French) we could use
the value 1 for Arabic, 2 for English, and 3 for French. Other programmers wouldn't know
the values for 1, 2 and 3 unless they find comments with these values. It will be more
readable if we do it with ordinal types as in the below example:

program OrdinalTypes;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
type
TLanguageType = (ltArabic, ltEnglish);
var
Lang: TLanguageType;
AName: string;

Compiled by Engineer Mulimbi Bricious 50


Selection: Byte;
begin
Write('Please select Language: 1 (Arabic), 2 (English)');
Readln(Selection);
if Selection = 1 then
Lang:= ltArabic
else
if selection = 2 then
Lang:= ltEnglish
else
Writeln('Wrong entry');
if Lang = ltArabic then
Write(' (' :‫ماهو اسمك‬
else
if Lang = ltEnglish then
Write('What is your name: ');
Readln(AName);
if Lang = ltArabic then
begin
Writeln(' ‫' مرحبا بك‬, AName);
Write(' ;('‫الرجاء الضغط على مفتاح إدخال لغلق البرنامج‬
end
else
if Lang = ltEnglish then
begin
Writeln('Hello ', AName);
Write('Please press enter key to close');
end;
Readln;
end.

Integer, character and boolean types are ordinal types, while real numbers and strings
are not.

Sets
Set types can hold multiple properties or characteristics in one variable. Sets are used
only with ordinal values. For example, if we need to define the operating system's support
for applications, we can do it as in the following:
1. Define ordinal type that represents operating systems: TApplicationEnv:
TApplicationEnv = (aeLinux, aeMac, aeWindows);
2. Define the application as set of TApplicationEnv: for example: FireFox: set of
TApplicationEnv;
3. Put operating system values in the application set variable: FireFox:= [aeLinux,
aeWindows];

program Sets;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes

Compiled by Engineer Mulimbi Bricious 51


{ you can add units after this };
type
TApplicationEnv = (aeLinux, aeMac, aeWindows);
var
FireFox: set of TApplicationEnv;
SuperTux: set of TApplicationEnv;
Delphi: set of TApplicationEnv;
Lazarus: set of TApplicationEnv;
begin
FireFox:= [aeLinux, aeWindows];
SuperTux:= [aeLinux];
Delphi:= [aeWindows];
Lazarus:= [aeLinux, aeMac, aeWindows];
if aeLinux in Lazarus then
Writeln('There is a version for Lazarus under Linux')
else
Writeln('There is no version of Lazarus under linux');
if aeLinux in SuperTux then
Writeln('There is a version for SuperTux under Linux')
else
Writeln('There is no version of SuperTux under linux');
if aeMac in SuperTux then
Writeln('There is a version for SuperTux under Mac')
else
Writeln('There is no version of SuperTux under Mac');
Readln;
end.

Also we can use set syntax for other ordinal types, like Integers:
if Month in [1, 3, 5, 7, 8, 10, 12] then
Writeln('This month contains 31 days');
Or character:
if Char in ['a', 'A'] then
Writeln('This letter is A');

Exception handling
There are two types of errors: compilation errors like using a variable without defining it
in the Var section, or writing statements with incorrect syntax. These types of errors
prevent the application from compiling, and the compiler displays a proper message and
points to the line containing the error. The second type is the runtime error. This type of
error occurs while the application is running, for example, division by zero, In a line like
this: x:= y / z; This is valid syntax, but at run time a user could enter 0 in the Z variable, and
then the application will crash and display a division by zero error message. Trying to
open a nonexistent file will generate a runtime error also (File not found), or trying to
create a file in a read only directory. The compiler cannot catch such errors, which only
occur after running the application. To build a reliable application that will not crash from
runtime errors, we should use exception handling. There are different methods of
exception handling in Object Pascal:

Compiled by Engineer Mulimbi Bricious 52


Try except statement
Syntax:
try
// Start of protected code
CallProc1;
CallProc2;
// End of protected code
except
on e: exception do // Exception handling
begin
Writeln('Error: ' + e.message);
end;
end;
Example for division:
program ExceptionHandling;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, sysutils
{ you can add units after this };
var
x, y: Integer;
Res: Double;
begin
try
Write('Input x: ');
Readln(x);
Write('Input y: ');
Readln(y);
Res:= x / y;
Writeln('x / y = ', Res);
except
on e: exception do
begin
Writeln('An error occurred: ', e.message);
end;
end;
Write('Press enter key to close');
Readln;
end.

There are two sections of the try statement. The first one is the block that we need to
protect, which resides between try … except. The other part exists between except .. end.
If something goes wrong in the first section (try except), the application will go to the
except section (except.. end) and it will not crash, but rather it will display the proper error
message and continue execution. This is the line that could raise the exception if the
value of y is zero:
Res:= x / y; If there is no exception, the except .. end part will not be executed.

Compiled by Engineer Mulimbi Bricious 53


Try finally
Syntax:
try
// Start of protected code
CallProc1;
CallProc2;
// End of protected code
finally
Writeln('This line will be printed in screen for sure');
end;
Division program using try finally method:
program ExceptionHandling;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
var
x, y: Integer;
Res: Double;
begin
try
Write('Input x: ');
Readln(x);
Write('Input y: ');
Readln(y);
Res:= x / y;
Writeln('x / y = ', Res);
finally
Write('Press enter key to close');
Readln;
end;
end.

This time the finally .. end part will be executed in all cases, regardless of whether there
is an error.

Raise an exception
Sometimes we need to generate/raise an exception to prevent some logical error. For
example if the user enters the value 13 for Month variable, we could raise an exception
telling him/her that he/she has violated the range of months.
Example:

program RaiseExcept;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}

Compiled by Engineer Mulimbi Bricious 54


Classes, SysUtils
{ you can add units after this };
var
x: Integer;
begin
Write('Please input a number from 1 to 10: ');
Readln(X);
try
if (x < 1) or (x > 10) then // raise exception
raise exception.Create('X is out of range');
Writeln(' X * 10 = ', x * 10);
except
on e: exception do // Catch my exception
begin
Writeln('Error: ' + e.Message);
end;
end;
Write('Press enter to close');
Readln;
end.

If the user enters a value outside of 1 to 10, an exception will be generated (X is out of
range), and if there is no exception handling for this part, the application will crash.
Because we have written try except around the code that contains the raise keyword, the
application will not crash, but instead it will display the error message.

Compiled by Engineer Mulimbi Bricious 55

You might also like