Read the Text Files





Hello, we meet again. I'm hope you're not bored yet. Now, we will discuss all things related to text files, like :

  1. Reading text files
  2. Writing text files
  3. Appending text files
  4. Additional commands : flush
  5. Error handling

What is text files actually ? It's just like this file, the read-me files, AUTOEXEC.BAT and CONFIG.SYS. All files with extension .INI are text files. This time we will discuss how to write or read one. Look at this :

var
  F : text;

F is a variable of text file. The first thing we must do is associate it with a file name, for example :

  assign(F,'README');

Before you can READ it, you must open it :

  reset(F);

You can read the file line by line, just like inputting user. Suppose s is a string variable :

  readln(F, s);

Note that the difference between normal readln with this kind of readln is the file variable F.

To know if user has reached end-of-file, function EOF will return true if the file has reached the end-of-file (EOF) marker :

  if EOF(F) then writeln('This is the end of text file');

After using that file, DON'T FORGET TO CLOSE IT. How ?

  close(F);

So, to read out all text file is just like this :


uses crt;
var
   F : text;
   s : string;
begin
   clrscr;
   write('Input file name to read : '); readln(s);
   assign(F,s);                { associate it }
   reset(F);                   { open it      }
   while not EOF(F) do         { read it until it's done }
   begin
     readln(F,s);
     writeln(s);
   end;
   close(F);                   { close it }
end.

Easy and simple, right ?

How to create one ? First thing you make is the same : associate the text variable with the filename using assign keyword. You then create it using rewrite instead of reset :

   rewrite(F);

Then, use your logic : To write lines into it use writeln instead of readln :

   writeln(F,s)    { s is a string variable }

And after writing all inside, don't forget to close it with the same close.

So, writing a text file is like this :


uses crt;
var
   F : text;
   s : string;
begin
   clrscr;
   write('Input file name to create : '); readln(s);
   assign(F,s);                { associate it }
   rewrite(F);                 { create it    }

   writeln('Just enter any text and followed by enter.');
   writeln('To quit : Input an empty line.');

   repeat
     readln(s);                { write it until done }
     if s='' then break;
     writeln(F,s);
   until true;

   close(F);                   { close it }
end.

Caution :
If you do rewrite an existing file, it means that you delete it and create a new one.

How can we just add some text without destroying it ? Well, use append instead. Change the rewrite in program above into append. Run them and see the difference.

Note : Before you run them, create a two identical text file for test. You could duplicate this file, but : Don't forget to make a backup for the original.

Pascal uses an internal buffer to store text-information. Buffer is a temporary place, usually an array or a pointer of a memory location. Pointer will be discussed in lesson 2. Buffer is employed to speed up (to cache) the process of reading or writing for any file, including text file. Buffer is limited in amount, but it is sufficient enough for processes in Pascal. If the buffer is full, Pascal flushed its contents to disk.

Now, sometimes you need to make sure that the buffer is not exceeding its maximum size. But, wait ... ! You said that it is sufficient enough ? Yes, it is. But flushing buffer manually can save the day. Say, the power line is suddenly down and the buffer contents haven't been written to disk. It IS tragic, isn't it ? You don't want your program user say 'AAAAaaaarrgggh, my data is LOST !', do you ?

Flushing buffer manually is done by adding flush(f); somewhere in your program before you close your file. Manual flush like this can only be done in text files. How about binary files ? Later, in the next chapter.

Now, we found that writing or reading files may not be as smooth as we have thought. Sometimes, in reading file, the file meant is not found, or having bad sector so that we cannot read it. If we don't employ the error-handling routine provided in Pascal, Pascal just shout 'Hey ! This is an error' then quits the program without notification.

This type of error-handling is pretty out-dated style since new error-trapping hadn't been invented in that time. But, I think it is sufficient for now, but it is a tiring task to do so. But, think about the user. Don't let the pain come. Here is the error-handling. Add this :


{$I-}     --> to make Pascal calm down when error shows up
  :       --> Do file process
{$I+}     --> to make Pascal detect what error is it if any

The error can be detected by invoking the function IOResult. If IOresult is 0, it means no error. For example :


uses crt;
var
   F : text;
   s : string;
begin
   clrscr;
   write('Input file name to read : '); readln(s);
   assign(F,s);                { associate it }

   {$I-}
   reset(F);                   { open it      }
   {$I+}
   if IOresult<>0 then
   begin
     writeln('Error encountered in reading file ',s);
     halt;
   end;

   while not EOF(F) do         { read it until it's done }
   begin
     readln(F,s);
     writeln(s);
   end;
   close(F);                   { close it }
end.

Yes, that's easy. Invoking IOresult causes the error code to reset. You may want to save its contents first to detect what error is it. Suppose n is an integer variable. I just modify a part of above program :


   :
   :
   {$I-}
   reset(F);
   {$I+}
   n:=IOResult;
   if n<>0 then
   begin
     writeln('Error encountered in reading file ',s);
     case n of
        2: writeln('File not found');
        3: writeln('Path not found');
        4: writeln('Too many open files');
        5: writeln('File access denied');
      100: writeln('Disk read error');
      101: writeln('Disk write error');
      150: writeln('Disk is write protected');
      152: writeln('Drive is not ready');
      154: writeln('CRC error in data');
      156: writeln('Disk seek error');
      157: writeln('Unknown media type');
      162: writeln('Hardware failure');
      else writeln('Various error');
     end;
     halt;
   end;
   :
   :

You see that you can detect it. In order to make your program free of error in run time, you must do this to EVERY input/output command, that means to every readln, reset, rewrite, writeln, append, and flush. Only assign and close do not need this. Phew, that must be a very tedious task.

Now that you have learnt error handling. Other error message can be seen in help (run-time error). Even this chapter is now finished, I still give you an EXTRA !

This extra is about detecting arguments / parameters passed in our program. Pascal provide two general "variables" that is : paramcount and paramstr. Paramcount is a word variable telling the number of parameters that is pas- sed into our program. Paramstr is an array of string containing the content s of the parameters. Example :

var
  n : word;
begin
  for n:=1 to paramcount do
  begin
    writeln(paramstr[n]);
  end;
end.

How can we test that program ? Should we get out of the IDE and run the EXE file ourself ? No need ! Borland Pascal provides a 'parameter simulation'. Check out the menu : Run then choose Parameters... You then asked the para- meters that will be passed into the program. Write any sentence or words in it then press enter. Run it and see what happens. Yes, it was just like running the EXE program in DOS prompt and passing the parameters manually. Easy, right ?

OK, that's all for now. Shall we go to the quiz or the next lesson ? Or you still don't understand ? Mail me !


Where to go ?

Back to main page
Back to Pascal Tutorial Lesson 1 contents
To the quiz
Back to Chapter 12 about making custom units
To Chapter 14 about binary files
My page of programming link
Contact me here


By : Roby Joehanes, © 1997, 2000