Once the programmer has the means to deal with numbers within programs, it also becomes necessary to print the answers to the screen where they can be seen by the program operator. The sample program module *powers* in section 2.3 contained the statement

WriteCard (exponent, 0);

for writing out the value of CARDINAL to the screen. There is also a *WriteInt* statement and both are, like *ReadCard* and *ReadInt*, imported from *SWholeIO* (Or, in non ISO Modula-2, from *InOut*). The second number in the *WriteInt* and *WriteCard* statements gives the size of the space to write in. Any extra spaces not needed for the number itself are placed to the left of the number. If not enough spaces are provided for, exactly the correct number will be taken. We say that the numbers are *right justified* in the specified field. That is,

WriteString ("the number is"); WriteCard (6, 0);

produces the output

the number is 6

with one space before the 6. (Zero room provided is handled as a special case in ISO standard Modula-2 and a single space is prefixed. In non ISO standard versions, there may be no space at all written in this situation.) The statements

WriteString ("the number is"); WriteCard (6, 3);

produce the output

the number is 6

with two spaces before the six, and the statements

int := -13; WriteString ("the number is"); WriteInt (int, 4);

produce the output

the number is -13

with a single space, because one of the four spaces allowed for is needed for the negative sign. Thus, the second number in *WriteCard* and *WriteInt* allow for some formatting of the output number. On the other hand, if one does not care how many spaces are used, the second number in *WriteInt* or *WriteCard* should be zero. This was done in the *powers* example, where the space between the strings and the numerals was created by putting spaces into the strings, rather than having them written by *WriteCard*. This method is preferred when the number of digits in the answer may vary and works in both ISO and non-ISO libraries.

(* display the result *) WriteCard (base, 0); WriteString ( " raised to the power "); WriteCard (exponent, 0); WriteString (" equals "); WriteCard (result, 0); WriteLn;

To illustrate, consider a program designed to print out a small table of cardinals (1 through 10) with their squares and cubes. The planning will not be given in detail, but the algorithm used can be expressed in pseudocode as:

print table headings set base to 1 while base <= 10 print base print square of base print cube of base increase base by one end while

If this algorithm is implemented as:

MODULESquareCube; (* by R. Sutcliffe *)FROMSTextIOIMPORTWriteString, WriteLn;FROMSWholeIOIMPORTWriteCard;VARbase:CARDINAL;BEGIN(* Write column headings *) WriteString ("Number "); WriteString ("Square "); WriteString ("Cube"); WriteLn; base := 1; (*on each line print first, second, and third powers of the base*)WHILEbase <= 10DOWriteCard (base, 0); WriteCard (base * base, 0); WriteCard (base * base * base, 0); base := base + 1; WriteLn;END;ENDSquareCube.

the output will look like this:

Number Square Cube 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000

because no spacing has been included. (In many non ISO versions, the numbers will be jammed together with no spaces at all, but the ISO standard requires one space to be output before the number in the special case that the room allowed is zero.) Putting one extra space into the WriteCard statements is not sufficient, for only the one digit numbers will then be properly separated. Instead, the program should lay out a well-spaced table. Moreover, this is a good place to use a constant, for the upper limit of the table may well be subject to change. If it is re-written as:

MODULESquareCubeFormatted; (* by R. Sutcliffe *)FROMSTextIOIMPORTWriteString, WriteLn;FROMSWholeIOIMPORTWriteCard;CONSTmaxToDo = 10;VARbase:CARDINAL;BEGIN(* write column headings *) WriteString (" Number"); (* allow 15 spaces for each *) WriteString (" Square"); WriteString (" Cube"); WriteLn; base := 1; (* on each line print first, second, and third power of base *)WHILEbase <= maxToDoDOWriteCard (base, 15); WriteCard (base * base, 15); WriteCard (base * base * base, 15); base := base + 1; WriteLn;END;ENDSquareCubeFormatted.

the output is

Number Square Cube 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000

There is also a procedure in *STextIO* (or in *InOut*) to output CHAR variables. This is the *WriteChar* statement (called *Write* when found in *InOut*,) and it too can output either literal characters, or those designated by constant or variable names. Here is a brief example:

VARch :CHAR;BEGINch := 'R'; WriteChar (ch); WriteChar ('.'); WriteChar ('S'); WriteChar ('.'); (* outputs my initials *)

and, another:

MODULEGetIt; (* by R. Sutcliffe *) (* prints out a little joke *)FROMSTextIOIMPORTWriteString, WriteLn, WriteChar;FROMSWholeIOIMPORTWriteCard;CONSTwye = "Y"; (* Character constants are allowed. *) four = 4;BEGINWriteChar (wye); WriteChar (wye); WriteString ("UR "); WriteChar (wye); WriteChar (wye); WriteString ("UB "); WriteChar ("I"); WriteChar ("C"); WriteString (" UR "); WriteChar (wye); WriteChar (wye); WriteCard (four, 2); WriteString (" ME!"); WriteLn;ENDGetIt.

the output of which is

YYUR YYUB IC UR YY 4 ME!