Question: What are text files and how can I use them?
Answer:
A text file is, obviously, a file that contains plain text. Turbo Pascal offers some procedures to handle such files and itÆs these procedures I will describe here.
First of all, a text file in Turbo Pascal is a monodirectional file which means you can only read from it or only write to it, but not both at the same time. If you want to read in some text you previously wrote to a file, you must close it first and reopen it for reading; ItÆs the same the other way round: before writing something to a file that is opened as readable, you must close it and open it again as writable.
To be able to use text files in a program, you must first include the unit dos to your program and then you must declare one or more variables that represent text files:
[color orange]
[/color]
Secondly, the basic operations that can be performed on a text file are: creating a file, writing to a file, closing one, reopening a file, reading from a file and appending to one. Before any of these operations can be performed, however, a physical file on a disk must be linked with a Turbo Pascal variable in which the name, the status and some attributes of the file will be stored during the run of a program. This is done with the procedure
:
[color blue]
Code:
file_variable : text; filename :
[/color]
The first parameter is the variable in which the file information will be stored, the second parameter is a string, containing a correct DOS file name that follows the 8.3 rule. This rule says that a file or directory name consists of at most 8 characters (only letters, digits and a limited set of special characters are allowed), optionally followed by a period and an extension of at most 3 characters (same constraints as for the first part). Also, a complete path cannot be longer than 68 characters. If the filename doesnÆt mention a path, the current directory is assumed. If the drive, path and/or file doesnÆt exist, no error occurs.
Now we have a variable, linked to a file, with wich we can perform all text file operations we want.
Following the assign statement, one of three procedures can be called to let DOS know how youÆre going to use the file. That is, wether you want to read from it, write to the end of it, or overwrite its contents.
[color blue]
[/color]
This procedure opens the text file for input; after this statement you will be able to use the
and
procedures (about which more later). If, for some reason, the physical file linked to the file variable doesnÆt exist when this procedure is called, a run-time error occurs saying ô[color red]file not found[/color]ö. If the drive or path doesnÆt exist, a ô[color red]path not found[/color]ö RTE occurs.
[color blue]
[/color]
The
routine opens the text file for output, so you will be able to use the
and
procedures (see later). All text that is written to a file that is opened like this, is added to the back of the file. Again, if the file doesn exist or if the drive or path is incorrect, RTEÆs ô[color red]file not found[/color]ö and ô[color red]path not found[/color]ö occur respectively.
[color blue]
[/color]
This routine makes the file ready to be written to, so that you can use
and
. If the file doesnÆt exist, it will be created and if it exists, the contents will be cleared. Here, the filename cannot be wrong, since the file is created if the name doesnÆt exist; however, directories are not automatically created, so you can still get the ô[color red]path not found[/color]ö RTE when the drive and/or path is incorrect.
IÆve mentioned the procedures
,
,
and
already and, since you now know how to open a text file, we can start using them.
[color blue]
Code:
dest_1 [, dest_2, à dest_n]);
[/color]
As you can see from the complicated header, the
procedure can take multiple variable parameters. The first two are mandatory: a file variable and a destination to store what is read. I will first describe what happens when using read with a single destination.
This routine will read from the current position in the file to the next separator. The separator depends on what the type of the destination variable is: is the destination is a string, everything until the end-of-line symbol is read (excluding the eol symbol itself). Since read doesnÆt skip the eol symbol, successive read operations with destinations of type string will return an empty string.
If the destination type is char, only one character at the time is read and there is no such thing as a separator. Also, no characters are skipped; as a consequence of this, you can determine what the end-of-line symbol is for strings (itÆs a combination of a carriage return and a line feed, so you will read [color green]#13[/color] followed by [color green]#10[/color]).
If the destination type is a number, all consecutive characters until the next space or end-of-line symbol (excluding that separator) are read as a number, all preceding spaces are skipped. If, however, a character that is neither a digit nor a separater is encountered, a RTE ô[color red]invalid numeric format[/color]ö occurs. If the destination type is real, a period and the scientific ôeö is allowed also. If the read value is out of bound, an ô[color red]invalid numeric format[/color]ö RTE occurs (e.g. reading [color green]'500'[/color] into a byte, [color green]'-100'[/color] into a word or [color green]'5.3645e-2054'[/color] into a real).
Self defined nor complex types can be read from a file (if you try it, you will get the compile error ô[color red]cannot read or write variables of this type[/color]ö).
Now, as for the multiple destination parameters: two or more consecutive read calls with the same file variable can be abbreviated to a single read call, passing all the destination parameters at once (they donÆt have to be all of the same type).
[color blue]
[/b]
[/b]
Code:
dest_1 [, dest_2, à dest_n]);
[/color]
This procedure does the same as
, with the difference that it continues reading until an end-of-line symbol is encountered. If there is more data in the file than there are destination variables, the destinations are filled and the rest of the data is discarded. If the type of a value in the file doesnÆt match that of the corresponding parameter, a RTE ô[color red]invalid numeric format[/color]ö occurs. If you donÆt want to read the current line in the file but just skip it, you can leave out a destination parameter.
Example:[color orange]
Code:
f : text;
i : integer;
r : real;
s : string;
readln(f,i,r,s);
[/color]
Is equivalent to[color orange]
Code:
read(f,i,r,s);
readln(f);
[/color]
And also to[color orange]
Code:
read(f,i);
read(f,r);
read(f,s);
readln(f);
[/color]
Warning: [color red]
Although read and readln are very versatile procedures regarding the number and types of parameters, it is advisable to only read into a single variable at the time. Your code will be much easier to read and to debug.[/color]
[color blue]
Code:
file_variable : text; source_1 [, source_2, à source_n]);
[/color]
This procedure writes data to a file; this one too can take an arbitrary number of parameters: a destination file and at least one value. The values to be written to the file can be both immediate constants or variable references and when a value of a certain type is written to the file, it can later be retrieved by reading it into a variable of the same type. Again, only simple types can be written, if you try to write a complex and/or self defined type, the compile error ô[color red]cannot read or write variables of this type[/color]ö occurs. Note also that
doesnÆt add separators to the file, you will have to do that yourself by writing a space.
[color blue]
Code:
file_variable : text; source_1 [, source_2, à source_n]);
[/color]
The only difference between this procedure and the previous, is that this one adds an end-of-line symbol after the last value is written to the file. If you want to only write an eol symbol to a file, you can drop the source variables.
Example:[color orange]
Code:
f : text;
i : integer;
r : real;
s : string;
writeln(f,i,Æ æ,r,Æ æ,s);
[/color]
Is equivalent to[color orange]
Code:
write(f,i,Æ æ,r,Æ æ,s);
writeln(f);
[/color]
And also to[color orange]
Code:
write(f,i);
write(f,Æ æ);
write(f,r);
write(f,Æ æ);
write(f,s);
writeln(f);
[/color]
When you opened a file and you have read or written data, you must close it again with the
procedure.
[color blue]
[/color]
This routine flushes the file buffer so that all data that was written to the file is acutally put on disk. After that it closes the file, which means that a DOS file handle is freed and the Turbo Pascal variable associated with the file can be used for another file. As long as there hasnÆt been performed an
operation on the file variable, the physical file is still linked to the variable, so that you can reopen it without having to call
again for the same file. If you try to read from a file that is closed, you will get the RTE ô[color red]file not open for input[/color]ö; when writing to a closed file, you wil get a ô[color red]file not open for output[/color]ö RTE.
IÆve now described the most important procedures that work with text files, but there are some other routines:
[color blue]
Code:
file_variable : text) : boolean;
Code:
file_variable : text) : boolean;
Code:
file_variable : text) : boolean;
Code:
file_variable : text) : boolean;
Code:
file_variable : text; new_name :
Code:
file_variable : text; [code][b][code]var[code][/b][code] attribute : word);
Code:
file_variable : text; attribute : word);
Code:
file_variable : text; [code][b][code]var[code][/b][code] time : longint);
Code:
file_variable : text; time : longint);
[/color]
writes the contents of the text file buffer to the physical file, just like
does. Note that this procedure dates from the early days of programming and personal computers and that nowadays disk caching systems make
to copy data from one buffer to another.
is a predicate that returns
when the current file position is behind the last element in the file.
does the same as
.
returns
if the current file position is an end-of-line symbol.
does the same as
.
deletes the element at the current file position and all elements that follow. The result is that
returns
after this operation.
deletes the file and its contents, the file must not be open when this procedure is called.
gives the file, linked with the given file variable a new name. If the new file name mentions a correct drive and/or path, the file is effectively moved to the new driver and/or directory by the operating system.
retrieves the file attributes of the file linked with the file variable. See the table below for possible values.
assigns new attributes to the file.
returns the date and time when the given file is created.
assigns a new creation date and time.
Note that the last two date-time values are compressed into a
which can be unpacked with
into a
record.
compresses a
record back into a
.
[color blue]
Code:
unpacktime(compressed : longint;
[/color]
File attributes are set with a bit pattern, there are seven Turbo Pascal constants denoting these attributes and a combination of these give a file certain properties:
Code:
readonly $01 1 00000001
hidden $02 2 00000010
sysfile $04 4 00000100
volumeID $08 8 00001000
directory $10 16 00010000
archive $20 32 00100000
anyfile $3F 63 00111111
If you have some comments or questions regarding this text or if youÆve seen a mistake, donÆt hesitate to contact me: vingerhoetsbert@hotmail.com.
----------------------------------------
This FAQ can also be downloaded in PDF format from my website.
Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
http://student.vub.ac.be/~bvingerh/
Don't worry what people think about you. They're too busy wondering what you think about them.
PS: Don't forget to rate!