WARNING: This example assumes spaces are ignored for the I and F descriptors.
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.
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
READ(*,"(I10,I10,I5)", IOSTAT=Status) SalesNo, Phone, Amount
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
Click here to download this program.
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.
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 getWRITE(*,"(A,I2,A,I2,A,I3)") " ", SN_1, "-", SN_2, "-", SN_3
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).
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
READ(*,"(2I2,I3,I6,I7,I5)", IOSTAT=Status) &
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
Click here to download this program.
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.