Pascal-Programming.info

A step-by-step Pascal tutorial for beginners.

Intro

A file contains data which is saved in the hard disk. You can only view a file from the hard disk by using an operating system. A can contain text data which is used by word processors. Many text files are saved in the hard disk with the extensions: *.txt and *.doc. The file with extension of *.txt, means that it is created by the Microsoft Notepad. Whenever you use the Microsoft Notepad and save a text file, this saved file is created and written on to the hard disk. However, some programs have various formats on how to maintain the text - such as justification, font, font colour. So many files contain more data other than text data! The program itself uses various techniques to create a file in such a way that, when it is being read again it can read (using programming skills, etc..) if it is justified, its font style etc..

Before you go on with files, please make sure that you have enough hard disk space for our experiments, since I am going to demonstrate to save a file to the hard disk!! :) Only a few bytes, however..

Read from a File (file input)

Reading a file in pascal is very easy. Note that there are no reserved words in Pascal that are used to to read or write to a file. We used the 'usual words': readln() and writeln(); Here's the technique of how to read a text file (only):

Program Lesson8_Program1;

Var UserFile : Text;
	FileName, TFile : String;

Begin
	Writeln('Enter the file name (with its full path) of the text file:');
	Readln(FileName); {A .txt file will be assigned to a text variable}
	Assign(UserFile, FileName + '.txt');
	Reset(UserFile); {'Reset(x)' - means open the file x}
	Repeat
		Readln(UserFile,TFile);
		Writeln(TFile);
	Until Eof(UserFile);
	Close(UserFile);
	Readln;
End.

It is worth to take a look at various important lines of the program. A new variable of type: 'Text' is new to you, and this should be used whenever you are going to edit a text file! The variable 'FileName' is required to link to the file indicated by the user. The 'assign' statement is used to declare 'FileName' + '.txt' to a text file, so that the file could be opened, using - 'Reset()'. To read from the first line to the very last line of the file, you should use the repeat-until loop, ending the loop with : 'Until Eof(textfile);', which means: 'Until the End Of File [eof]'.

Create and Write to a File (file output)

The following program is an example of how to create-and-write or overwrite a file:

Program Lesson8_Program2;
Var
	FName, Txt : String[10];
	UserFile   : Text; 

Begin
	FName := 'Textfile';
	Assign(UserFile, 'C:\'+FName+'.txt'); {assign a text file}
	Rewrite(UserFile); {open the file 'fname' for writing}
	Writeln(UserFile, 'PASCAL PROGRAMMING');
	Writeln(UserFile, 'if you did not understand something,');
	Writeln(UserFile, 'please send me an email to:');
	Writeln(UserFile, 'victorsaliba@hotmail.com');
	Writeln('Write some text to the file:');
	Readln(Txt);
	Writeln(UserFile, '');
	Writeln(UserFile, 'The user entered this text:');
	Writeln(UserFile, Txt);
	Close(UserFile);
End.            

In the above program, I am using the 'writeln()' statement so that I write to the file I have previously assigned to. Note that, even though I am using writeln(), there is no output to the screen, it goes to the file I initialised referred to by 'UserFile'.

To check exactly what has just been written to this file, go to C:\, and see if there is a file named:

Textfile.txt. Open it and see what does it contain!! :-). If you encountered any difficulties in locating the file, then in the start menu go to:

start -> find -> files or folders => look in drive C: and enter 'textfile.txt' in the text box; double click on it.

Append text to an existing File

Writing to an existing file, means, open a file and add extra data, but not overwrite the contents file. Some beginner programmers do not actually understand how to not overwrite a file with data they would like to input. This is the common problem:

Var
	UFile : Text;

Begin
	Assign(UFile, 'C:\ADDTEXT.TXT');
	ReWrite(UFile); 
	Writeln(UFile, 'How many sentences ' +
		+ 'are present in this file?');
	Close(UFile);
End.

Copy the program above in your Pascal compiler. Run this program for two times or more. After you run this program several times, find the file named 'addtext.txt'. Is there more than one sentence?

A new function which works with files, can solve our problem. This function is called 'append(f)', where f is a variable of type text. This can be done by simply changing the 'Rewrite(UFile)' to 'Append(UFile)', and the file contents are not overwritten, but appended!

The above program can be changed to the following:

Var
	UFile : Text;

Begin
	Assign(UFile, 'C:\ADDTEXT.TXT');
	Append(UFile); 
	Writeln(UFile, 'How many sentences, '+
		+'are present in this file?');
	Close(UFile);
End.

Run the program two times or more to see the change...

Delete Files

In Pascal, the reserved word used to delete files from the hard this is the 'Erase(f)' where f is a variable of any data type. This means that 'f' could be both file and text variable type. Note, that the file you are about to delete is not taken in the recycle bin, but it is directly kicked off the hard disk!!

Unlike any other file functions, the Erase() function does not open the file to delete it, so you don't need to call Close(...) after Erase().

Example Program:

Var
	UFile : Text; { or it could be of 'file' type}

Begin
	Assign(UFile, 'C:\ADDTEXT.TXT');
	Erase (UFile); 
End.

The '{$I-},{$I+}' compiler directives

Compiler directives are used to adjust the compiler settings during the compilation process, so that programmers can control their program in their preferrable way. Compiler directives are declared using the symbols '{', '$' and '}'. Note that the braces are used for comments, but still, '{$something}' is taken to be a directive. Instead of 'something' the programmer should replace it by a known directive (a letter). Now, the '{$I}' is used to tell the compiler not to take into consideration I/O errors including file operations. Say, for example, if a file is trying to be opened, but it does not exist, the program does not stop from executing and halts with a runtime error, saying: 'File not found' or whatever annoying error! Make sense? So, if you apply this compiler directive before you open the file, either for writing or reading, I/O errors will not cause the program to raise a runtime error forced halt.

Now, I must teach you how to use this compiler directive by letting you know where to put it and how to cater with the error that might occur. It must be placed where you are going to open or delete a file. ie.:

{$I-}
actions on file...
{$I+}
{ enable the I/O error check again }

It is important to enable again the i/o error check, after you have disabled it, so that any unknown future errors would be automatically encountered. However, if you think that it would be better to disable i/o error checking for the entire program, you can! Just apply the directive at the beginning and that's it but it is not recommended since during the runtime of your program you will not be notfied of IO errors that might occur!! After you control a file action, you must check whether an error has occured or not by using the system function 'IOResult', which returns IO error information. This is a typical traditional exception handling. You should test for errors using the statement:

If (IOResult <> 0) Then ...

The IOResult function should be explicitly used after an IO error check so that it will automatically clear the error flag of the system otherwise, the IO error cause a 'mutation' to other IO processes resulting into a runtime error. You are not required to grasp each word perfectly from what I said. The most important thing is that you include that statement if the IO directives are to be used and everything would be fine. Now I should show you how to use it by an example:

Program Lesson8_Program3;
Uses Crt;

Var
	t : Text;
	s : String;

Begin
	Assign(t, 'C:\ABC.DEF');
	{$I-}   { disable i/o error checking }
	Reset(t);
	{$I+}   { enable again i/o error checking - important }
	If (IOResult <> 0) Then
	Begin
		Writeln('The file required to be opened is not found!');
		Readln;
	End Else 
	Begin
		Readln(t,s);
		Writeln('The first line of the file reads: ',s);
		Close(t);
	End;
End.

If the required file is found the IOResult returns a 0 value, meaning no errors; ELSE if not found (IOResult returns a non-0 value) display an error message!

IMPORTANT: if the file is successfuly found, the file is opened and you should close it as shown in the program above. However, if it is not found, the common sense says that it couldn't be opened because it is not found!?! So, you should not include a 'close(..)' after it is not opened and this is done conditionally as shown in the example. Study carefully my program and run it several times with good paths and non-good ones to see well the difference and how does the compiler directive works!!

Hopefully, the compiler directive could be applied to different functions, similarly as in the program above. You can use it with 'Rewrite()', 'Append()', 'Erase()', and also 'FSearch()'. You can try as many programs as you wish and hopefully practicing the IO directive. I know, that this directive is somewhat complex and hard to be understood but undoubtedly useful! I am there waiting for your e-mails, if you think that your program does not work properly when using this directive.

Create and Remove Sub-Directories

In Pascal, there are functions with which you can either create or remove a directory from the hard disk. To create a directoy, we use the function 'CreateDir(c)' where 'c' is of type PChar. Ohh, that's sound kinky... What the heck does PChar means? Hehe, PChar is a pointer variable which holds the address of a dynamic variable of a specified type. It is sort of a pointer for characters. Before you create the directory, however, you have to check if the directory exists, else a runtime error shows up fiddling in front of your monitor!! :-) The directory is created as follows:

NewDir := FSearch('C:\Pascal Programming', GetEnv(''));    
If NewDir = '' Then
	CreateDir('C:\Pascal Programming');

From only three lines of code, we have been able to create a dir. But, before you go experimenting on your own, you should strictly read the following documented example: (I will explain in detail the 'FSearch()' function)

Program Lesson8_Program4;
Uses
	WinDos, Dos;  { note the inclusion of the 'windos.tpu' library }

Var
	NewDir : PathStr; { for searching the dir and create a new one, if it does not exist }
	F : Text;

Begin
	{ search for the dir }
	NewDir := FSearch('C:\Pascal Programming', GetEnv('')); 
	{ create a new one, if it does not exist }
	If NewDir = '' Then
		CreateDir('C:\Pascal Programming'); 
	Assign(F,'C:\Pascal Programming\pprogramming.txt');
	{$I+} ReWrite(F); {$I-} { disable and enable back again 
                           i/o error checking } 
	{ write to text file } 
	Writeln(F,'http://pascal-programming.info/'); 
	{$I+} Close(F); {$I-}
End.

The variable type, 'PathStr', is new to you, and this is a variable defined in the 'dos.tpu' library. So, you have to include the 'dos' library at the beginning of your program. The 'FSearch()' function is implemented also in the windos library to search in a dir list. So, it was useful in our program and any other program to search if the dir exists or not. It's not important to know exactly what does 'GetEnv()' mean, which is found in the second parameter of FSearch(). The Borland Turbo Pascal reference says that its function is to return the value of the specified function. Note that 'FSearch()' is implemented in the 'dos.tpu' library, while CreateDir()' is implemented in the 'windos.tpu' library.

To remove a directory, it is quite simple. Just add 'remove()' at the end of your program! :-) Your operating system will automatically erase the dir if it exists. It doesn't matter if you 'remove' a dir which does not exist. Hopefully, no runtime errors, will show up! The 'remove(Pch)' function is also implemented in the windos library, where 'Pch' is a variable of type PChar, again.

FileSize() - Return the value of a file in bytes

Now, for the fun stuff!! To return the size of a file, simply declare a variable of 'longint' type, and assign it to the filesize of the file. A file variable of type byte, should be assigned to the file which you would like to return its size, using 'Assign()'.

Program Lesson8_Program4;
Var
	f : File of Byte; { file var of type byte }
    sz : LongInt;  { var for the size }

Begin
	Assign(f,'C:\anyfile.txt');
	{$I-} Reset(f); {$I+}
	If (IOResult <> 0) Then
 	Begin     { file found? }
  		Writeln('File not found.. exiting');
  		Readln;
 	End Else
 	Begin
  	{ Return the file size in Kilobytes }
  		sz := Round(FileSize(f)/1024);
  		Writeln('Size of the file in Kilobytes: ',sz,' Kb');
  		Readln;
  		Close(f); 
 	End;
End.

Comments