WARNING:This example assumes spaces are ignored for theIandFdescriptors and the output is sent to a printer.

Write a **Fortran** to read in two sequences of numbers and computes
their inner product.

Suppose we have an input like the following. The first line gives the
number of input values. Each of the input line has two fields with 10
positions each. **You should use only one format
to read all data items**.

Your program should produce the following output report.1 ....5....0 5 4 7 2 -1 6 2 -3 4 -2 -3

1 1 2 2 3 ....5....0....5....0....5....0 Input Data No X Y 1 4 7 2 2 -1 3 6 2 4 -3 4 5 -2 -3 Input product = 32

ClickPROGRAM InnerProduct IMPLICIT NONE INTEGER, PARAMETER :: SIZE = 50 INTEGER :: Number, Sum, i INTEGER, DIMENSION(1:SIZE) :: x, y CHARACTER(LEN=80) :: Fmt1, Fmt2, Fmt3 Fmt1 = "(I5/(2I5))" Fmt2 = "(1X,A//1X,3A5/(1X,3I5))" Fmt3 = "(/1X, A, I7)" READ(*,Fmt1) Number, (x(i), y(i), i = 1, Number) WRITE(*,Fmt2) "Input Data", "No", "X", "Y", & (i, x(i), y(i), i = 1, Number) Sum = 0 DO i = 1, Number Sum = Sum + x(i)*y(i) END DO WRITE(*,Fmt3) "Input product = ", Sum END PROGRAM InnerProduct

The output of the program is:1 ....5....0 5 4 7 2 -1 6 2 -3 4 -2 -3

1 1 2 2 3 ....5....0....5....0....5....0 Input Data No X Y 1 4 7 2 2 -1 3 6 2 4 -3 4 5 -2 -3 Input product = 32

- Let us study the way of reading in the input with only one format.
The number of data items can be read in with
**I5**and each subsequent input line can be read in with**2I5**. We can read the input with two**READ**s and two formats. But, if you recall the meaning of**/**, you will know that after reading in the number of data items, we can use**/**to terminate the current line. At a first glance, we could use**(I5/2I5)**. But, this is incorrect, because this format is equivalent to**(I5/I5,I5/I5/I5,I5/....)**. More precisely, it reads in one integer from the odd numbered lines and two integers from the even-numbered lines. This certainly cannot fit our input.Since

**I5**is used only once and**2I5**is used a number of times, to repeat**2I5**, what we have to do is enclosing**2I5**in a pair of parenthesis:**(I5/(2I5))**. By the way,**(I5/2(I5))**would do the job (why?); but I prefer**(I5/(2I5))**. So, the following is the**READ**statement and the format:Fmt1 = "(I5/(2I5))" READ(*,Fmt1) Number, (x(i), y(i), i = 1, Number)

- Now let us turn to the output. The
**WRITE**and format are shown below:Fmt2 = "(1X,A//1X,3A5/(1X,3I5))" WRITE(*,Fmt2) "Input Data", "No", "X", "Y", & (i, x(i), y(i), i = 1, Number)

**1X,A**prints the title**Input Data**. Then,**//**produces a blank line between the title and the table heading.**No**,**X**and**Y**are printed with**1X,3A5**. The next**/**terminates the heading line, meaning that subsequent output starts with the next output line. Now, we see the grouping again, which means**1X,3I5**will be used over and over until all data items are printed.Let me remind you that there is no need to have a

**/**after**3I5**like this:Fmt2 = "(1X,A//1X,3A5/(1X,3I5/))" WRITE(*,Fmt2) "Input Data", "No", "X", "Y", & (i, x(i), y(i), i = 1, Number)

**Fortran**always terminates the current input or output line and all subsequent input and output will be on the next line. If we have**(1X,3I5/)**, this means after printing three integers, the current line is terminated and output will be performed on the next line. Then,**Fortran**sees the closing right parenthesis, which terminates the current line. Therefore, this line has nothing but spaces. This implies that the table is double-spaced:1 1 2 ....5....0....5....0 Input Data No X Y 1 4 7 <--- 1X,3I5/ <--- printed due to end of format 2 2 -1 <--- 1X,3I5/ <--- printed due to end of format 3 6 2 <--- 1X,3I5/ <--- printed due to end of format 4 -3 4 <--- 1X,3I5/ <--- printed due to end of format 5 -2 -3 <--- 1X,3I5/ <--- printed due to end of format

- The result (
*i.e.*, inner product) is printed the following way:Fmt3 = "(/1X, A, I7)" WRITE(*,Fmt3) "Input product = ", Sum

**/**so that we will have a blank line between the table and the result. Thus, this tells you that**/**can be used to produce blank lines. -
**Could the two formats for writing be combined into a single format?**Because we have shown examples of combining a number of formats into one, this is a natural question. Unfortunately, this**cannot**be done at this moment. Suppose the format is combined as follows:Fmt = "(1X,A//1X,3A5/(1X,3I5)//1X, A, I7)" WRITE(*,Fmt) "Input Data", "No", "X", "Y", & (i, x(i), y(i), i = 1, Number), & "Input product = ", Sum

**//**between**(1X,3I5)**and**1X,A,I7**. This is because we need a blank line between the table and the result. This format does not work, simply because it is equivalent to the following:(1X, A // 1X, 3A5 / 1X, 3I5 // 1X, A, I7 / 1X, 3I5 // 1X, A, I7 / 1X, 3I5 // 1X, A, I7 / .....) WRITE(*,Fmt) "Input Data", "No", "X", "Y", & (i, x(i), y(i), i = 1, Number), & "Input product = ", Sum

**3I5**is followed by a blank line, followed by**1X, A, I7**. This is incorrect since**A**is not allowed to print**INTEGER**s.Of course, if we know the number of repetitions of

**1X,I5**, say 25, then the format can be rewritten asFmt = "(1X,A//1X,3A5/25(1X,3I5)//1X, A, I7)" ^^ ^^------ 25 is added here WRITE(*,Fmt) "Input Data", "No", "X", "Y", & (i, x(i), y(i), i = 1, Number), & "Input product = ", Sum

*e.g.*, internal files), which will be discussed later. Click**here**for some details.