Internal Files: The Most Fundamental Facts

We have learned to read from the keyboard and write to the screen or a printer. With a minor modification, we can read from or write to a CHARACTER variable! This is the most fundamental concept of the so-called internal files. We will not discuss the full features of internal files until the concept of files will be covered later. We shall only discuss how to read from and write to a CHARACTER variable. Note that we said a CHARACTER variable rather than a CHARACTER array. Of course, an element of a CHARACTER array is a CHARACTER variable.

You can use listed-directed or formatted READ and WRITE statements. We used (*,*) and (*,Format) for list-directed and formatted input/output, respectively. The first asterisk indicates the location (i.e., keyboard, screen or printer) for carrying the input/output operations. If you want to read from or write to a CHARACTER variable, just use that variable's name or array element to replace the first asterisk:

CHARACTER(LEN=100) :: ReadBuffer
CHARACTER(LEN=100) :: OutputLine

CHARACTER(LEN=50), DIMENSION(1:20) :: Line

READ(ReadBuffer, ....)  .......
WRITE(OutputLine, ....) .......

READ(Line(3), .....)    .......
WRITE(Line(k), .....)   .......

Reading from a CHARACTER variable

In the case of a READ, the CHARACTER variable must have been stored some content so that reading can be carried out. You can consider the content of that CHARACTER variable as a single input line. So, do not use / for line advancing and format rescanning (format rescanning will cause line advancing).

Here is an example:

CHARACTER(LEN=40) :: Line
INTEGER           :: a, b, c

Line = "123  67 89 1 3 "
READ(Line,"(BZ,3I5)")  a, b, c
In this case, the content of variable Line is
         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
123  67 89 1 3
READ(Line,"(BZ,3I5)") a, b, c means to read in three integers for variables a, b and c using format (BZ,3I5). The "source" of input is from CHARACTER variable Line as if it is an input line. In the format, BZ means treating blanks as zeros.

The first five positions contain "123  " and are treated as "12300". Therefore, variable a receives 12300. The next five positions contain "67 89" and are treated as "67089". Therefore, variable b receives 67089. The next five positions contain " 1 3 " and are treated as "01030". Thus, variable c receives 1030.

Writing to a CHARACTER variable

Writing to a CHARACTER variable is similar to writing to an output line, except that printer control is not needed. As in the READ case, do not use / or format rescanning for line advancing because you have only one line, the CHARACTER variable. Also keep in mind that do not write more characters than the length of the CHARACTER variable.

Here is an example:

CHARACTER(LEN=40) :: Line
INTEGER           :: a = 15, b = 30, c = 9

WRITE(Line, "(2X, SS, I3.3, T10, I5, SP, I4)")  a, b, c
The CHARACTER variable Line has 40 characters for storing the output. When the WRITE starts, we see 2X, followed by SS (no plus sign should be printed), followed by I3.3. Therefore, the first five positions of Line contain the following:
         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
  015
Format scanning continues with T10 followed by I5. Therefore, positions 10 to 14 contain the output value of b using I5. Thus, we have:
         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
  015       30
Then, we see SP (plus sign must be printed), followed by I4. Therefore, the value of c is printed in positions 15 to 18. Note that a plus sign is printed since the value of c (i.e., 9) is positive. The result is:
         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
  015       30  +9
Since the end of format is reached and all variables have been printed, this WRITE completes. All remaining positions (i.e., 19 to 40) contain blanks as in an output line sent to the screen. Therefore, if you know how to read from the keyboard and write to the screen, you know how to read from and write to a CHARACTER variable.

An Example

Here is a very simple example. Click here to download a copy.
PROGRAM  Test
   IMPLICIT NONE
   CHARACTER(LEN=40)         :: Buffer
   INTEGER, DIMENSION(1:100) :: X
   INTEGER :: i

   WRITE(Buffer,"(10I4)") (i, i = 1, 10)
   WRITE(*,*)  Buffer
   WRITE(*,*)
   READ(Buffer,"(BN,8I5)")   (X(i), i = 1, 8)
   WRITE(*,*)                (X(i), i = 1, 8)
   WRITE(*,*)
   READ(Buffer,"(BZ,8I5)")   (X(i), i = 1, 8)
   WRITE(*,*)                (X(i), i = 1, 8)
END PROGRAM Test
This program generates the following output:
         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
   1   2   3   4   5   6   7   8   9  10

           1           2           3          45           6           7
           8         910

          10         200        3000       40005          60         700
        8000       90010