Creating a list using <fstream> and nested if/else

So I am doing a homework assignment but I do not understand if I am doing it right or absolutely wrong on how I am using the <fstream> with a while loop and nested if/else . The bottom part is still a work in progress the question says: A bank charges $10 per month plus the following check fees for a commercial checking account:

$0.10 each for fewer than 20 checks
$0.08 each for 20-39 checks
$0.06 each for 40-59 checks
$0.04 each for 60 or more checks

The bank also charges an extra $15.00 if the balance of the account falls below $400 (before any check fees are applied). Write a program that asks for the beginning balance and the number of check written. Compute and display the bank's service fees for the month.

Input Validation: Do not accept a negative value for the number of checks written. If a negative value is given for the beginning balance, display an urgent message indicating the account is overdrawn.

I was also wondering if there was an easier way to do something like this with less of the nested if/else or is this the only way?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# include<iostream>

# include<iomanip>

# include<fstream>

using namespace std;

int main()

{
	double startingBalance, checksWrote;
	
	ifstream input;

	input.open("transaction.txt");
	
	while (input>>startingBalance>>checksWrote)//while loop

    {	
	 int range1, range2, range3,overDrawn;
	 range1=20,
	 range2=39,
	 range3=59,
	 overDrawn=400;

	 const double TEN_CENTS=.10,
		      EIGHT_CENTS=.08,
		      SIX_CENTS=.06,
		      FOUR_CENTS=.04,
		      MONTHLYFEE=10,
		      EXTRAFEE=15;
	 double totalFee;
				 	
				 	
	 cout<<setprecision(2)<<fixed<<"Begginging balance: $"<<startingBalance<<endl;
		cout<<setprecision(0)<<fixed<<"Number of checks written: "<< checksWrote<<endl;
		cout<<setprecision(2)<<fixed<<endl;

		if (startingBalance < 0)
		{
		cout<<"Your account is overdrawn!";
		}
		 else if (startingBalance < overDrawn)
		{
			totalFee = (totalFee += EXTRAFEE);
		}
			if (checksWrote >= 0)
			{
				if (checksWrote >= range1)
				{
					if (checksWrote >= range2)
					{
						if (checksWrote >= range3)
						
					}
				}
			}
                      //Processing the checks

    }//end while loop
}
Last edited on
Hello DrCoke21,

I tent to take a different approach to programs. For your code the first thing I would work on is reading the file.

Which by the way you should post the input file so everyone can use the same information when dealing with your program. If it is large at least a fair sample, (5 to 10 lines or records).

My first question is how do you know that the file stream is open and usable?

I use this when dealing with "fstream"s:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
	double startingBalance{}, checksWrote{};

	std::string inFileName{ "transaction.txt" };

	std::ifstream inFile(inFileName);

	if (!inFile)
	{
		std::cout << "\n File " << std::quoted(inFileName) << " did not open" << std::endl;
		//std::this_thread::sleep_for(std::chrono::seconds(3));  // <--- Needs header files chrono" and "thread". Optional
		return 1;  //exit(1);  // If not in "main".
	}

Line 3 is there to point out that it is a good idea to initialize your variables. This becomes even more true when you define double totalFee; in the while loop.

The reason for line 13 is that you do not want to continue with the program until you fix the problem.

These lines:
1
2
3
4
5
int range1, range2, range3, overDrawn; // <--- Would consider making these constant.
range1 = 20,
range2 = 39,
range3 = 59,
overDrawn = 400;


Could be written as:
1
2
3
4
5
int range1{ 20 }, range2{ 39 }, range3{ 59 }, overDrawn{ 400 }; // <--- Would consider making these constant.
//range1 = 20,
//	range2 = 39,
//	range3 = 59,
//	overDrawn = 400; 


And these lines:
1
2
3
4
5
6
7
const double
	TEN_CENTS = .10,   // <--- Stored as 0.10000000000000000056
	EIGHT_CENTS = .08, // <--- Stored as 0.08000000000000000167
	SIX_CENTS = .06,   // <--- Stored as 0.05999999999999999778
	FOUR_CENTS = .04,  // <--- Stored as 0.04000000000000000083
	MONTHLYFEE = 10.0,
	EXTRAFEE = 15.0;

For the last two lines this would be the proper to initialize a "double".

Watch your use of blank lines and indenting. I missed the opening brace of the while loop the first time I looked at your code. It was to far to the left and I was not expecting that.

The while condition is a good start.

Inside the while loop I noticed the use of "overDrawn" is misleading. Something like "MINIMUNBALANCE" or "MINBALANCE" is more descriptive and it should be defined as a constant.

The line totalFee = (totalFee += EXTRAFEE); may work, but does not make much sense. I think what you may want here is totalFee += EXTRAFEE;.

The if statement on line 52 is looking for its closing }. The closing } on line 56 is actually paired with the if statement on line 54. For now you could put a ';' on line 55 to make it work correctly.

Not that it appears to be a problem, but on line 44 you are comparing a "double" to an "int".

As for what you are doing from line 40 on I have not worked on that part yet until I have some data to work with.

That is a start for now.

Andy
Inexperienced programmers often store money as floating point. But if you think about it, it's really an integer: the number of cents. You can convert input from dollars.cents to cents and output from cents to dollars.cents.
@dutch,

I was thinking about that, but considered that OP may not be ready for it yet.

Then again I should have mentioned that.

Andy
Another beginner mistake is naming constants like

 
TEN_CENTS = 10

This is useless. It says no more than simply saying 10 in the first place.

This would be better:

1
2
3
4
const int FewerThan20 = 10,
          From20To39  =  8,
          From40To59  =  6,
          MoreThan59  =  4;

Or perhaps even something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

struct Fees {
    int amount;
    int fee;
};

const Fees CheckFees[] {
    { 20,  10},
    { 40,   8},
    { 60,   6},
    {  0,   4},
};

int main() {
    int numChecks = 0;
    while (std::cout << "Num checks: ", std::cin >> numChecks) {
        int size = sizeof CheckFees / sizeof *CheckFees;
        int i = 0;
        for ( ; i < size; ++i)
            if (CheckFees[i].amount == 0 || numChecks < CheckFees[i].amount)
                break;
        std::cout << "Fee: " << CheckFees[i].fee << '\n';
    }
}

Last edited on
@OP There's merit in some of the comments here. Take note but don't sweat the finer points if you are just starting off. Double precision is good enough - banks and payroll companies have traditionally worked to 4 decimal places to cover 9 figure imprecision.

Keep using namespace std to avaoid all the std:: 's which confuse the basic issues you asked about.

Overall, the tidy up I did leaves your framework pretty much because its on track.
Make sure you check what I've done as far as meeting the spec. I haven't, it's your assignement, not mine :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# include<iostream>
# include<iomanip> // <- FORMATTING THE OUTPUT IS A LOW PRIORITY
# include<fstream>

using namespace std;

int main()

{
    double startingBalance = 0.0, checksWritten; // <-- BETTER (ENGLISH) NAME
    
    const double TEN_CENTS =.10,
    EIGHT_CENTS =.08,
    SIX_CENTS =.06,
    FOUR_CENTS =.04,
    MONTHLY_FEE = 10,
    OVERDRAWN_FEE = 15; // CLEARER NAME
    
    int range1 = 20, range2 = 39, range3 = 59, overDrawn = 400;
    
    double totalFee = 0.0;
    
    ifstream input;
    input.open("transaction.txt");
    
    while (input>>startingBalance>>checksWritten)
    {
        // OVERDRAWN FEE
        if (startingBalance < overDrawn)
        {
            cout<<"Your account is overdrawn!\n";
            totalFee += OVERDRAWN_FEE; // <--
        }
        
        // FEE FOR NUMBER OF CHECKS WRITTEN - START AT THE TOP
        if (checksWritten > range3)
        {
            totalFee += checksWritten * FOUR_CENTS;
        }
        else if (checksWritten > range2)
        {
            totalFee += checksWritten * SIX_CENTS;
        }
        else if(checksWritten > range1)
        {
            /* blah blah*/;
        }
        else
        {
            /* blah blah*/;
        }
        
        // OUTPUT THE RESULTS
        // CHECKOUT THIS WAY OF cout'ing
        cout
        <<setprecision(2)<<fixed
        <<"Beginning balance: $"<<startingBalance<<endl
        <<setprecision(0)<<fixed
        <<"Number of checks written: "<< checksWritten<<endl
        <<setprecision(2)<<fixed<<endl;
        
        /* cout BLAH BLAH ON FEES */
        //Processing the checks
        
    }//end while loop - NOT NECESSARY TO STATE THE OBVIOUS
}
I would like to thank everyone for the useful advice on the usage of fstream and how to make use of the if/else and if/else if as well as just making it more logical and nicer to look at.
Topic archived. No new replies allowed.