Trying to not use all global variables...getting an error

Pages: 123
I'm working on not using all global variables for my programs. So what am I doing wrong here? I thought I did have my variables declared in the beginning of the function that will use them? My understanding here is very introductory, so please bear with me.
I get the error:
31| error: 'rateA' was not declared in this scope.

And I get that same error for all 5 variables.
My other question is what do I need to put in the return statement for this function to be able to use these variables in the next function I write that will actually create the table?

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
//*************************************************************
//This program generates a table of factors used to
//compute monthly payment amounts for money borrowed.
//Again, this program does NOT compute monthly payment,
//only a table of factor values.
//*************************************************************

#include <iostream>//Header files
#include <cmath>
#include <fstream>
#include <iomanip>

using namespace std;

ofstream outfile;//File descriptor

//Prototypes
int openOutfile(); //Function opens the answer outfile
int getValues(double rateA,  double rateB, double inc, int yearA, int yearB);//Function gets interest rate range, increment, and year range
void createTable();//Function creates a table of factors using user-provided values to compute

//Begin main
int main()
{
    openOutfile();
    getValues(rateA, rateB, inc, yearA, yearB);
    createTable();

    return 0;
}

int openOutfile()
{
    outfile.open("answers.out");//Open an outfile for answers
    if( !outfile) //Check to see if outfile opens correctly
    {
        cout << "Error opening output file." << endl; //If it doesn't open correctly, display message
        return 0;                                     //and quit.
    }
}

int getValues()
{
    double rateA, rateB, inc;
    int yearA, yearB;
    cout << "Enter interest rate range (two values)," << endl
         << "and increment amount separated by spaces." << endl;
         cin >> rateA >> rateB >> inc;
    cout << "Enter the year range amount separated by a space." << endl
         << "ex. 1 15" << endl;
         cin >> yearA >> yearB;
    return (//I have no idea what goes here!
}

void createTable()
{

}
You could create the variable, rateA... etc. in main, and pass them to a function, by reference, i.e:

1
2
3
4
5
6
7
8
9
10
11
12
13
void getValues( double &rateA ) // note the ampersand '&'
{
    // do stuff
}

int main()
{
    double rateA;

    getValues( rateA ); // now rateA is what ever was set in the function

    return 0;
}


Or... You could do the following, and return the double:

1
2
3
4
5
6
7
8
9
10
11
12
13
double getValues()
{
    // do stuff...

    return aDoubleVariable;
}

int main()
{
    double rateA = getValues(); // rateA now equals what was set in the function

    return 0;
}
Can you return more than one thing? That's probably a stupid question, sorry. Also, can I pass them all by reference, since for this program, they won't change?
Last edited on
It's not a stupid question! I remember asking this question before!

You can't( as far as I now know... ) return more than one variable.
Every time I've needed more than one returned, I've coded the first snippet from my first post! Pass by reference and the vales which are set within the function will reflect in the function that called it.

EDIT:
You can pass as many as you like by reference. I'm not sure if C++ limits( the amount of ) parameters in any way.
Last edited on
22
23
24
25
26
27
28
29
30
//Begin main
int main()
{
    openOutfile();
    getValues(rateA, rateB, inc, yearA, yearB);
    createTable();

    return 0;
}
If you ever have a problem like this again, think: 'where are those variable names coming from?' and you'll usually be able to solve your problems with ease ;)
Thanks so much. I do feel very not smart when I program. But it feels pretty awesome when I get it right.
I've been working on this one, and I still need to do the meat of it, really, but so far, I think it's going well. My next question is, is there an easier way to create a table WITHOUT using an array? Should I just continue going line by line with maybe a loop somehow? That's what I am trying to do, I'm just having trouble with the loop part:
Here is what I have so far, and it is missing the table part, which will have the years, yearA though yearB as 'row headers' and then the columns will be labelled with rateA through rateB going by the inputted increment (inc.)

If you run it, you will see the beginning of my table, but I'm a little stuck on getting the actual table to work out right...but I'm trying. :)

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
67
68
69
//*************************************************************
//This program generates a table of factors used to
//compute monthly payment amounts for money borrowed.
//Again, this program does NOT compute monthly payment,
//only a table of factor values.
//*************************************************************

#include <iostream>//Header files
#include <cmath>
#include <fstream>
#include <iomanip>

using namespace std;

ofstream outfile;//File descriptor

//Prototypes
int openOutfile(); //Function opens the answer outfile
void getValues(double &mortgage, double &rateA,  double &rateB, double &inc, int &yearA, int &yearB);//Function gets interest rate range, increment, and year range
void createTable(double &mortgage, double &rateA, double &rateB, double &inc, int &yearA, int &yearB);//Function creates a table of factors using user-provided values to compute

//Begin main
int main()
{
    double mortgage, rateA, rateB, inc;//Declare variables
    int yearA; int yearB;

    openOutfile();
    getValues(mortgage, rateA, rateB, inc, yearA, yearB);
    createTable(mortgage, rateA, rateB, inc, yearA, yearB);

    return 0;
}

int openOutfile()
{
    outfile.open("answers.out");//Open an outfile for answers
    if( !outfile) //Check to see if outfile opens correctly
    {
        cout << "Error opening output file." << endl; //If it doesn't open correctly, display message
        return 0;                                     //and quit.
    }
}

void getValues(double &mortgage, double &rateA,  double &rateB, double &inc, int &yearA, int &yearB)
{
    cout << "Enter amount to borrow." << endl;
         cin >> mortgage;
    cout << "Enter interest rate range (two values)," << endl
         << "and increment amount separated by spaces." << endl;
         cin >> rateA >> rateB >> inc;
    cout << "Enter the year range amount separated by a space." << endl
         << "ex. 1 15" << endl;
         cin >> yearA >> yearB;
    return;
}

void createTable(double &mortgage, double &rateA,  double &rateB, double &inc, int &yearA, int &yearB)
{

    for (int count = 0; count < yearB; count++ );
    {
        cout << "       Monthly Payment Factors Used in Computing Monthly Payments" << endl;
        cout << "                             Interest Rates                      " << endl;
        cout << endl;
        cout << "Years" << endl;

    }
}



Unless you want to hard-code every possible situation, I suggest using dynamic arrays (tricky to deal with) or a class that does it all for you, such as std::vector.
http://www.cplusplus.com/reference/stl/vector/
1
2
3
4
5
std::vector<double> MyArray;
MyArray.push_back(7.67);
MyArray.push_back(21.62);
MyArray.push_back(3.1415926);
for(unsigned int i = 0; i < MyArray.size(); ++i) cout << MyArray[i] << endl;

As you can see, it's pretty simple and flexible. And to pass it around to functions, you can use references:
vector<double> &SomeVector
;)
Last edited on
Arrays do seem much simpler, but our teacher specifically told us not to use arrays. He wrote: "You can NOT use an array. This is a formatting and nested loop problem (and maybe some thinking.) You will compute one factor at a time and then print that value in a nice table format with row and column labeling for each table as shown above. (*The shown above format looks like my table, but with numbers in it.*)
He did give us formulas to calculate what number will be in each box of the table, but I don't understand how to incorporate all that.
He gave us:
Monthly payment =
(I +1)^N * I
__________ * Mortgage
(I + 1)^N - 1

where I= 1/12th of the interest rate
N= total months in term

How the heck do I begin?
Last edited on
Oh, yeah he is right that you don't need arrays. You're only dealing with one data set at a time, you don't need to store all the data at the same time!
Well, I'm glad someone seems to understand what I'm doing. Lol.
Write your program to work with one data set. Then, put it in a loop and you're done ;)
Last edited on
Obviously, this is wrong, because it doesn't do anything differently than the code above did, but am I getting any closer? Do I need to do a separate loop for the top line of rates? Where am I going wrong with my for loop? That's what I'm trying to do here...a suggestion would be awesome.

Below is my createTable function that isn't quite working...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void createTable(double &mortgage, double &rateA,  double &rateB, double &inc, int &yearA, int &yearB)
{

    for (int count = yearA; count == yearB; count++ );
    {
        cout << "       Monthly Payment Factors Used in Computing Monthly Payments" << endl;
        cout << "                             Interest Rates                      " << endl;
        cout << endl;
        cout << "Years" << endl;
        for (double rate = rateA; rate == rateB; rate + inc)
        {
            cout << "      " << rate << "  ";
        }
    }
}
Last edited on
for (int count = yearA; count == yearB; count++ );
1. If yearA != yearB, this code never runs
2. The semicolon at the end is the only statement this for loop loops. The code in the braces on the following lines will always run one time because it is not part of the for loop. Essentially you are doing this:
1
2
3
4
5
6
7
8
for(int x = y; x == z; ++x)
{
    ;
}

{
    //your code
}


Your loop on line 10 also has the same problem but you fixed the semi-colon issue.
Last edited on
Break the for-loop down:

double rate = rateA; while rate is equal to rateB( run statements within loop ); rate + inc;

So, if rate is equal to rateB, this loop will only do one itteration as rate will change and no longer be equal to rateB.
Oh, I thought that second bit in the for loop is the ending value? No? I thought it would keep looping around until that statement was true. Is there a loop that does that?
I got something to happen! It's not correct, but it's progress! Here's where I am now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void createTable(double &mortgage, double &rateA,  double &rateB, double &inc, int &yearA, int &yearB)
{

    for (int count = yearA; count <= yearB; count++ )
    {
        cout << "       Monthly Payment Factors Used in Computing Monthly Payments" << endl;
        cout << "                             Interest Rates                      " << endl;
        cout << endl;
        cout << "Years" << endl;
        for (double rate = rateA; rate <= rateB; rate + inc)
        {
            cout << "      " << rate << "  ";
        }
    }
}


This prints what looks like pretty wavy lines of rateA. So I'm still way off, but at least the loops are running, right? And yes, it's an infinite loop, but I'm working on it! :)
a while-loop! lol (:

say you want to run something until something is true, or visa-versa, you would do something like:

1
2
3
4
5
6
7
8
bool running = true;

while( running ) 
{
    // do stuff

    // change 'running'...
}

If you want the opposite, just use the !( not ) opperand ( I think it's called that? lol )
i.e.
while( ! running )
true is false, and visa versa.

Or, you could use a for-loop, like so:
1
2
3
4
for( int i = 0; i != variable; ++i ) // i = 0, while i is NOT equal to some variable, run code, after run, increment i
{
    // do stuff...
}


EDIT:
On another note, when you use:
outfile.open("answers.out");

You'll also want to use:
outfile.close();

Otherwise, when you're program exits, you'll still have this file open in memory, i.e. a memory leak!

Use the .close() statement just before the return of main:
1
2
3
outfile.close();

return 0;


EDIT 2:
Only use this before the return of main as you have the file in global scope. When you open and use a file in a single function, close the file before the function end, as it wont be in scope to close there after.
Last edited on
It's not so much an ending value, as much as it's the conditional that "continues" the loop. As long as the conditional evaluates to true, it continues to run. A couple examples:

1
2
3
4
for (int i = 0; i < 3; i++)
{
    infile >> p[i].x >> p[i].y >> p[i].z;
}


The for statement initializes i to 0, loops through post-incrementing it by 1 and checks it against 3 to see if it is less than 3. Once it hits 3, it terminates. As long as i < 3, the condition evaluates as true.

Here's another example:

1
2
3
4
5
6
7
8
9
10
11
12
13
	for( list<Triangle>::iterator trit = tri_list.begin(); trit != tri_list.end(); trit++ )
	{
		tri = *trit;
		for( int i = 0; i < 3; i++ )
		{
			bb[MIN].x = minimum(bb[MIN].x, tri.X(i) );
			bb[MIN].y = minimum(bb[MIN].y, tri.Y(i) );
			bb[MIN].z = minimum(bb[MIN].z, tri.Z(i) );
			bb[MAX].x = maximum(bb[MAX].x, tri.X(i));
			bb[MAX].y = maximum(bb[MAX].y, tri.Y(i));
			bb[MAX].z = maximum(bb[MAX].z, tri.Z(i));
		}
	}


Sets trit to the start of the list, loops through, post-incrementing trit by 1 and checks it's "value" against tri_list.end(). However, the conditional is different this time around. In the former case, we checked if it was less than. Here we are check to make sure it does not equal and as long as trit does not equal the end of the list, it evaluates as true.

If you need to loop while something is !=, then you probably want to write:

 
for (double rate = rateA; rate != rateB; rate + inc)


However, you'll need to ensure that rate will at some time == rateB or have some condition to terminate the loop or return from the function or you'll be spinning in place forever.

Almost missed this: rate will not increment. The last part of the for loop does not store the new value back into rate. You need to update the value and store it back in rate so that it can be checked against rateB with the updated value.
Last edited on
I have a problem incrementing. Can I only increment by 1? I'm trying to increment by increments of the variable incr but it isn't working. I've tried adding rate + incr to the end of the for loop, but the rate never changes. At least now I have a table though... Can't I use a variable to increment by in the loop?
+ just adds two things together, it doesn't change either of them.
+= adds the variable on the left to the variable on the left, changing the variable on the left to its current value plus the variable on the right.

You would want to use +=
Pages: 123