Printing a File Containing CTRL+Z Characters

Product Version(s): 3.3x
Operating System:   MS-DOS
Flags: ENDUSER | TAR21449
Last Modified: 30-SEP-1988    ArticleIdent: Q10868

Question:

Printing fails when attempting to print out hexadecimal character 1A
(CTRL+Z) with the following command:

writeln(prn,chr(26));

If written to the printer, you get "Error 1028 device full in file
PRN". We used the following assignment to print CTRL+Z:

   VAR prn : text;
   begin
   assign(prn,'prn');
   rewrite(prn);
   writeln(prn,chr(26));

Is this problem occurring because chr(26) is the end-of-file marker
(CTRL+Z)? Can you eliminate this problem by using write or writeln?

Response:

This problem occurs because of the DOS interpretation of CTRL+Z, which
is chr(26). When DOS is processing a file and encounters a CTRL++Z
character, it interprets the CTRL+Z character as an
end-of-file (EOF) marker.

In your example, you are sending a file containing the CTRL+Z
character to the printer. DOS interprets the character as the end of
the file, causing anything after the CTRL+Z not to be printed. Pascal
recognizes that it was not able to print out all that it should have
and interprets that to mean that the printer was full. This behavior
causes the "device full" error.

The filename PRN is reserved by DOS for the printer device. Read,
readln, write, and writeln all read/write data to/from textfiles. When
you write a line to PRN (printer device) using writeln, you are trying
to write a line of a textfile to the printer, as in the following
example:

writeln(prn,chr(26));

Textfiles are files of type text and always have an ASCII structure.
Because DOS always interprets CTRL+Z characters in ASCII files as
EOF markers, DOS interprets this CTRL+Z as the EOF marker and quits.

Thus, in Pascal and FORTRAN you cannot send CTRL+Z to either standard
output (filename OUTPUT) or to the printer (filename PRN). If you
were instead trying to send output to a binary file (FILE OF <type>),
DOS would allow you to send a CTRL+Z.

Do the following to work around this behavior of DOS:

1. Ensure that your output contains only printable ASCII characters
   (this is the recommended method).

2. Trap errors on output (PRN.TRAP := true) and then decide what to
   do when an error occurs, e.g. try to print a CTRL+Z. If
   you were using some other filename reserved by DOS (such as USER)
   with OUTPUT), you should write an assembler or MS-C routine to check
   that standard input/output has been redirected.

3. Direct output to a file instead of to the printer or standard
   output. (Please note that this does not resolve your specific problem
   in which the objective is to print the CTRL+Z character at the
   printer device.)

4. One other possibility is to put all of your data/characters into
   a binary (FILE OF <type>) file. This is a workaround for the DOS
   interpretation of a CTRL+Z character because DOS does not do any
   interpretation of a binary file; DOS only sends it on to the printer.
   Be careful if you use the binary-file approach because the compiler
   and DOS interpret the information contained in a binary file
   differently.

In general, do the following:

1. Make sure that output contains only printable ASCII characters.
   In particular, do not try to write a CTRL+Z to a TEXT file, i.e.,
   do not send a CTRL+Z to OUPUT, PRN, USER, etc.

2. If you still want to be able to send a CTRL+Z to output, you
   must redirect output to a binary file or check for the CTRL+Z using
   error trapping.
