# Print a Check Record ### Problem Statement

Suppose we have an input of the following form. There are unknown number of input lines. The first character of each line is D, d, P, p, C or c, where D and d means deposit, P and p means payment, and C and c means a check balance should be printed.
```         1    1
....5....0....5
D     +123\$\$\$\$\$
d      +78\$\$\$\$\$
c    \$\$\$\$\$\$\$\$\$\$
P    \$\$\$\$\$  +50
D     +100\$\$\$\$\$
D      +10\$\$\$\$\$
p    \$\$\$\$\$ +120
C    \$\$\$\$\$\$\$\$\$\$
P    \$\$\$\$\$  +50
D     +150\$\$\$\$\$
```

If the first character is a D or d, this is a deposit line. In this case, positions 6 to 10 contain the deposit amount and positions 11 to 15 contain \$\$\$\$\$ so that nobody can overwrite this field. If the first character is a P or p, this is a payment line. In this case, positions 6 to 10 contain \$\$\$\$\$ and positions 11 to 15 contain the payment amount. If the first character is a C or c, then positions 6 to 15 contain \$\$\$\$\$\$\$\$\$\$.

Write a Fortran program that reads in these input lines and prints the following table.

```         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
Check Book Reference Listing
============================

Count   Payment   Deposit   Balance
-----   -------   -------   -------
1   *******      +123      +123
2   *******       +78      +201
-----------------------------------
3        +0      +201      +201
-----------------------------------
4       +50   *******      +151
5   *******      +100      +251
6   *******       +10      +261
7      +120   *******      +141
-----------------------------------
8      +170      +311      +141
-----------------------------------
9       +50   *******       +91
10   *******      +150      +241
-----------------------------------
Total      +220      +461      +241
```

This table has four columns. The first column prints the transaction numbers. The second column contains the payment amount. It should contain the amount of payment if that transaction is a payment line; otherwise, it should contain *******. The third column contains the deposit amount. It should contain the amount of deposit if that transaction is a deposit line; otherwise, it should contain *******. The fourth column contains the balance after each transaction is made.

If the input line is a C or c, then your program should print a dashed line, followed by the total payment and total deposit up to this point, and the current balance, followed by another dashed line. At the end of the report, a dashed line followed by the total payment, total deposit and current balance must be printed. ### Solution

```PROGRAM  CheckBook
IMPLICIT   NONE
CHARACTER(LEN=1)  :: Code
CHARACTER(LEN=15) :: Line
INTEGER           :: Payment, Deposit, Balance, Input
INTEGER           :: Count
INTEGER           :: Status
CHARACTER(LEN=*), PARAMETER :: Filler      = "   *******"
CHARACTER(LEN=*), PARAMETER :: DashLine    = "-----------------------------------"
CHARACTER(LEN=*), PARAMETER :: TitleFormat = "(1X, A/1X, A//1X, A/1X, A)"
CHARACTER(LEN=*), PARAMETER :: InputLine   = "(A)"
CHARACTER(LEN=*), PARAMETER :: CheckLine   = "(1X, A/ 1X, I5, SP, 3I10/1X, A)"
CHARACTER(LEN=*), PARAMETER :: PaymentLine = "(1X, I5, SP, I10, A, I10)"
CHARACTER(LEN=*), PARAMETER :: DepositLine = "(1X, I5, A, SP, 2I10)"
CHARACTER(LEN=*), PARAMETER :: LastLine    = "(1X, A/ 1X, A, SP, 3I10)"

WRITE(*,TitleFormat)  "Check Book Reference Listing",        &
"============================",        &
"Count   Payment   Deposit   Balance", &
"-----   -------   -------   -------"

Payment = 0
Deposit = 0
Balance = 0
Count   = 0
DO
IF (Status < 0)  EXIT
Code  = Line(1:1)
Count = Count + 1
SELECT CASE (Code)
CASE("C", "c")
WRITE(*,CheckLine)  DashLine, Count, Payment, Deposit, Balance, DashLine
CASE("P", "p")
Payment = Payment + Input
Balance = Balance - Input
WRITE(*,PaymentLine)  Count, Input, Filler, Balance
CASE("D", "d")
Deposit = Deposit + Input
Balance = Balance + Input
WRITE(*,DepositLine)  Count, Filler, Input, Balance
END SELECT
END DO

WRITE(*,LastLine)  DashLine, "Total", Payment, Deposit, Balance
END PROGRAM  CheckBook
```
Click here to download this program. ### Program Input and Output

If the input data consist of the following:
```         1    1
....5....0....5
D     +123\$\$\$\$\$
d      +78\$\$\$\$\$
c    \$\$\$\$\$\$\$\$\$\$
P    \$\$\$\$\$  +50
D     +100\$\$\$\$\$
D      +10\$\$\$\$\$
p    \$\$\$\$\$ +120
C    \$\$\$\$\$\$\$\$\$\$
P    \$\$\$\$\$  +50
D     +150\$\$\$\$\$
```
The output of the program is:
```         1    1    2    2    3    3    4
....5....0....5....0....5....0....5....0
Check Book Reference Listing
============================

Count   Payment   Deposit   Balance
-----   -------   -------   -------
1   *******      +123      +123
2   *******       +78      +201
-----------------------------------
3        +0      +201      +201
-----------------------------------
4       +50   *******      +151
5   *******      +100      +251
6   *******       +10      +261
7      +120   *******      +141
-----------------------------------
8      +170      +311      +141
-----------------------------------
9       +50   *******       +91
10   *******      +150      +241
-----------------------------------
Total      +220      +461      +241
``` ### Discussion

The computation of this problem is easy and will not be discussed. We shall only focus on the difficult spot of this problem.
• So, where is the difficult spot? It is in the input instead of output. Why? A false impression may lead you to design the following format for reading in each input line:
```(A, 4X, 2I5)
```
That is, the A is for reading in the first character, 4X to skip the next four spaces, and 2I5 for reading in the deposit and payment values. This seems a reasonable format; however, it just does not work. Let us examine the first input line. D is read into a CHARACTER variable, four spaces are skipped by 4X and the first I5 reads in a deposit value. But, the second I5 will cause a problem because the next five positions contain \$\$\$\$\$ which do not form a valid integer. Similar reason holds true for a payment line. For a line with C or c in the first position, both I5s will cause the same problem. So, the above format just does not work.
• A second thought is that: If the first position is a D or d, then we read the integer in positions 5 to 10 and ignore the content in positions 11 to 15; if the first position is a P or p, then we read the integer in position in positions 11 to 15 and ignore the content in positions 6 to 10; and finally if the first position is a C or c, then we ignore the content in positions 6 to 15. A very good analysis. indeed. The question is before you read in a line, how do you know which type it is? This is the big question. In other word, before we can read in a line, we really do not know if it is a deposit line or a payment line!
• To solve this problem, let us read a line anyway. How do we read in a line without knowing its type? Very simple. Just read it in as a CHARACTER string! So, an input line is read in as follows:
```CHARACTER(LEN=15)           :: Line
CHARACTER(LEN=*), PARAMETER :: InputLine   = "(A)"

```
After this, we have the complete line in our hand so that we could examine it over and over again without getting into format troubles.
• How do we examine this input line Line? We need to take a look at its first character. When we discuss substring, we learn that x(i:j) is the content of position i to position j of string x. Therefore, Line(1:1) is the first character of Line. A simple SELECT CASE statement would do the job:
```Code  = Line(1:1)
SELECT CASE (Code)
CASE("C", "c")
this is a balance line
CASE("P", "p")
this is a payment line
CASE("D", "d")
this is a deposit line
END SELECT
```
• If we know the type of the input line, we can use an appropriate format to read it. For example, if it is a deposit line, then we need the value in positions 6 to 10:
```READ(Line,"(T6,I5)")   Input
```
Thus, the deposit value is read into variable Input. Note that this value is read in from the input line which is now stored in Line rather than directly from the keyboard input.
• The remaining is simple and will not be discussed