# The Phone Numbers Problem: Revisited

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

### Problem Statement

We shall redo the salesperson number and phone number problem discussed previously in INTEGER input and in CHARACTER input. In fact, we shall modify the latter version using nX and Tc edit descriptors.

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 gives the 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
CHARACTER(LEN=2)  :: SN_1, SN_2, SN_3*3
CHARACTER(LEN=3)  :: Phone_1, Phone_2*4
INTEGER           :: Amount
INTEGER           :: Number
INTEGER           :: Status
LOGICAL           :: Problem
CHARACTER(LEN=10) :: TitleFormat   = "(T8,A)"
CHARACTER(LEN=30) :: InputFormat   = "(A2,A2,A3,3X,A3,A4,3X,I5)"
CHARACTER(LEN=30) :: OutputFormat  = "(1X, 5A, T14, 3A, T26,I6)"
CHARACTER(LEN=30) :: LastLine      = "(1X, A, I3, A)"

WRITE(*,TitleFormat)    "Sales Amount Table"
WRITE(*,TitleFormat)    "=================="
WRITE(*,*)
WRITE(*,HeadingFormat)  "Sales No.   Phone No.   Amount"
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(*,OutputFormat)  &
SN_1, "-", SN_2, "-", SN_3, Phone_1, "-", Phone_2, Amount
Number = Number + 1
END IF
END DO
IF (.NOT. Problem) THEN
WRITE(*,*)
WRITE(*,LastLine)  "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

• The first difference you will see is that the printer control characters are not part of the WRITE statements. They are parts of the formats. This makes the WRITE statements more meaningful, because your readers will not be confused by the " " in each WRITE statement.
• Second, leading spaces in the strings for the table headings are gone. They also become parts of formats. Take a look at the desired output.
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Sales Amount Table
==================
:
:
:
```
The table heading "Sales Amount Table" starts at position 8 and as a result we can use T8 to move there rather than adding spaces into the string. Thus, we have a CHARACTER variable TitleFormat for this purpose:
```CHARACTER(LEN=10) :: TitleFormat   = "(T8,A)"

WRITE(*,TitleFormat)    "Sales Amount Table"
WRITE(*,TitleFormat)    "=================="
```
• The headings of the columns are shown below. It is simple, because we still can use a single string for the entire column heading. This heading starts at position 2, leaving position 1 for printer control.
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
Sales No.   Phone No.   Amount
---------   ---------   ------
:
:
:
```
The following are the format and WRITE statements. We have a CHARACTER variable to store the format in which T2 is used to move to position 2:
```CHARACTER(LEN=10) :: HeadingFormat = "(T2,A)"

WRITE(*,HeadingFormat)  "Sales No.   Phone No.   Amount"
```
• Since we know the way of skip positions (i.e., the nX edit descriptor), we do not have to read in the spaces in input lines. Thus, we can use A2, A2 and A3 to read in the three components of a salesperson's number, followed by 3X to skip the three spaces. Do the same for the phone number. Thus, we have the following format and READ statement:
```CHARACTER(LEN=30) :: InputFormat   = "(A2,A2,A3,3X,A3,A4,3X,I5)"

SN_1, SN_2, SN_3, Phone_1, Phone_2, Amount
```
• If we look at the numbers in the table, we shall see that the salesperson number starts at position 2, his/her phone number at position 14, and bonus amount at 26 (so that it can be printed using I6):
```         1    1    2    2    3    3
....5....0....5....0....5....0....5
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
```
You can use T2 to move to position 2 or 1X to skip the first position. The remaining two fields can be positioned using T14 and T26. The following is the format and the READ statement:
```CHARACTER(LEN=30) :: OutputFormat  = "(1X, 5A, T14, 3A, T26,I6)"

WRITE(*,OutputFormat)  &
SN_1, "-", SN_2, "-", SN_3, Phone_1, "-", Phone_2, Amount
```
• The last line is easy.
• From this example, it is easily seen that the use of nX and Tc can simplify the construction of formats. In what follows, we shall use these two edit descriptors freely and will never go back to the clumsy techniques used previously. You are encouraged to rewrite all previous examples using nX and Tc.