# INTEGER Input

 WARNING: This example assumes spaces are ignored for the I and F descriptors.

### Problem Statement

Suppose we have an input like the following. Each row starts with a salesperson's number (10 positions), followed by his/her phone numbers (10 positions), followed by the bonus this person has earned. Each salesperson's number has seven digits, the first two are division code, followed by two digits of department code, followed by three digits of person code. A phone number has seven digits in the form of 482-0911.
```         1    1    2    2
....5....0....5....0....5
7645094   7079173   1000
8745363   6347862   1120
8701001   7130067   750
4000023   6700175   1253
8801810   9000018   980
```
Write a Fortran program that reads in the above input and prints the following table:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Sales Amount Table
==================

Sales No.   Phone No.   Amount
---------   ---------   ------
76-45-094   707-9173      1000
87-45-363   634-7862      1120
87-01-001   713-0067       750
40-00-023   670-0175      1253
88-01-810   900-0018       980

Total  5 person(s) processed.
```
Note that the first position is always for printer control. Note also that we do not know the number of salespersons.

### Solution

```PROGRAM  Decoding
IMPLICIT  NONE
INTEGER :: SalesNo, Phone, Amount
INTEGER :: SN_1, SN_2, SN_3
INTEGER :: Phone_1, Phone_2
INTEGER :: Number
INTEGER :: Status
LOGICAL :: Problem

WRITE(*,"(A,A)")  " ", "      Sales Amount Table"
WRITE(*,"(A,A)")  " ", "      =================="
WRITE(*,*)
WRITE(*,"(A, A)")  " ", "Sales No.   Phone No.   Amount"
WRITE(*,"(A, A)")  " ", "---------   ---------   ------"
Problem = .FALSE.
Number = 0
DO
IF (Status > 0) THEN
WRITE(*,*)  "Something wrong in your input data"
Problem = .TRUE.
EXIT
ELSE IF (Status < 0) THEN
EXIT
ELSE
SN_3 = MOD(SalesNo, 1000)
SN_2 = MOD(SalesNo/1000,100)
SN_1 = SalesNo/100000

Phone_2 = MOD(Phone, 10000)
Phone_1 = Phone / 10000
WRITE(*,"(A,I2.2,A,I2.2,A,I3.3,I6.3,A,I4.4,I10)")  &
" ", SN_1, "-", SN_2, "-", SN_3, Phone_1, "-", Phone_2, Amount
Number = Number + 1
END IF
END DO
IF (.NOT. Problem) THEN
WRITE(*,*)
WRITE(*,"(A,A,I3,A)")  " ", "Total", Number, " person(s) processed."
END IF
END PROGRAM  Decoding
```

### Program Input and Output

The output of the program is:
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Sales Amount Table
==================

Sales No.   Phone No.   Amount
---------   ---------   ------
76-45-094   707-9173      1000
87-45-363   634-7862      1120
87-01-001   713-0067       750
40-00-023   670-0175      1253
88-01-810   900-0018       980

Total  5 person(s) processed.
```

### Discussion

• Since we do not know the number of input lines, a READ statement with IOSTAT must be used.
• Since the first and the second numbers occupy positions 1 to 10 and positions 11 to 20, we can use I10 and I10. The third number can be found in positions 21 to 25 and can be read with I5. Therefore, the input format is (I10,I10,I5). You certainly can change it to (2I10,I5).
• The three numbers on each input line are read into variables SalesNo, Phone and Amount.
• To convert the salesperson number to the form of xx-yy-zzzz from the value stored in SalesNo, we need to observe the following:
1. The last four digits can be obtained with MOD(SalesNo,1000). That is, these four digits can be obtained by taking the remainder of dividing SalesNo by 1000.
2. The first two digits is the quotient of dividing SalesNo by 100000.
3. The middle two digits can be obtained with MOD(SalesNo/1000,100). Suppose the number stored in SalesNo is 7645094. Dividing this number by 1000 yields 7645. The remainder of dividing 7645 by 100 is 45, which is the middle two digits.
• Now, we have all three parts in SN_1, SN_2 and SN_3. How do we print them into a form of xx-yy-zzz? The following just does not work:
```WRITE(*,"(A,I2,A,I2,A,I3)")  " ", SN_1, "-", SN_2, "-", SN_3
```
The reason is simple. Suppose 9005003 is decomposed into 90, 05 and 003. Then, SN_1, SN_2 and SN_3 contains 90, 5 and 3. If they are printed with the above format, we shall get
```         1
....5....0
90- 5-  3
```
More precisely, the leading zeros are not printed. To force printing the leading zeros, the format must be changed to (A,I2.2,A,I2.2,A,I4.4).
• The phone number can be handled the same way.

Some of you may have the following idea. Why don't we just read in the components? This is a good point. Here is a possible solution:

```PROGRAM  Decoding
IMPLICIT  NONE
INTEGER :: Amount
INTEGER :: SN_1, SN_2, SN_3
INTEGER :: Phone_1, Phone_2
INTEGER :: Number
INTEGER :: Status
LOGICAL :: Problem

WRITE(*,"(A,A)")  " ", "      Sales Amount Table"
WRITE(*,"(A,A)")  " ", "      =================="
WRITE(*,*)
WRITE(*,"(A, A)")  " ", "Sales No.   Phone No.   Amount"
WRITE(*,"(A, A)")  " ", "---------   ---------   ------"
Problem = .FALSE.
Number = 0
DO
SN_1, SN_2, SN_3, Phone_1, Phone_2, Amount
IF (Status > 0) THEN
WRITE(*,*)  "Something wrong in your input data"
Problem = .TRUE.
EXIT
ELSE IF (Status < 0) THEN
EXIT
ELSE
WRITE(*,"(A,I2.2,A,I2.2,A,I3.3,I6.3,A,I4.4,I10)")  &
" ", SN_1, "-", SN_2, "-", SN_3, Phone_1, "-", Phone_2, Amount
Number = Number + 1
END IF
END DO
IF (.NOT. Problem) THEN
WRITE(*,*)
WRITE(*,"(A,A,I3,A)")  " ", "Total", Number, " person(s) processed."
END IF
END PROGRAM  Decoding
```

In this solution, SN_1, SN_2, SN_3, Phone_1, Phone_2 and Amount are read with (2I2,I3,I6,I7,I5). This format looks odd; however, we can make it better after X and T are discussed. Why does this format work? The following illustrates the reason. 2I2 retrieves the first two two-digit numbers marked with ++ and --. The next I3 reads in the next three digits marked with ***. Then, I6 takes three spaces and the first three digits of the phone number (marked with ^^^^^^), and I7 takes the next four digits along with the four trailing spaces (marked with |||||||). Finally, I5 is for reading Amount.

```         1    1    2    2
....5....0....5....0....5
7645094   7079173   1000
++--***^^^^^^|||||||~~~~~
```

This format only works for "regular" input. If the input is changed to the following, the above solution will not work properly. However, the original solution works fine. Please figure out the reason.

```         1    1    2    2
....5....0....5....0....5
7645094   7079173   1000
8745363     6347862 1120
8701001  7130067  750
4000023   6700175   1253
8801810   9000018   980
```

Yet another solution will be discussed using CHARACTER variables. Click here to study this solution.