Functions combining

I am trying to make sure I understand functions, so I am writing a small program to re-enforce my learning. The first one is:

1
2
3
4
5
  float getBudget(float car, float plane, float hotel)
	{
	float budget = car + plane + hotel;
	return budget;
	}


The other is this one:

1
2
3
4
5
 float myBudget(PersonalInfo &Budget)
{
	float getBudget = car + plane + hotel;
	return myBudget;
}


The first one adds them and the second one stores it into the struct. I have tried to re-write it this way to reduce code:

1
2
3
4
5
6
7
 float myBudget(PersonalInfo &Budget, float car, float plane, float hotel)
{
	float getBudget = car + plane + hotel;
	cout << "Your Budget is: " << getBudget << ".";
	return getBudget;

}


When I call it in the program, it does not work. The error codes are:

1
2
3
4

identifier " getBudget" is undefined
'getBudget':identifier not found


Should I leave them separate and store the value in my struct in another way, or is there a way to combine them and cout the total?



What code do you have in the program where the call doesn't work? How is the struct defined?
Hello SlowBug2319,

The first function code looks good and looks like it should work. Although I would suggest using "double"s over "float"s.

In the second function the return value is a float, but you are trying to return a struct. This will not work.

I the third function You are passing in a struct, but never use it. There is nothing in the code that shows me that you are storing any information in the struct. And if the point of the function is to store information in the struct, what is the purpose of the return value?

Your error message is lacking some information. Two functions use the variable "getBudget", so which function does the error message refer to?

It would be helpful to see all of your code including the definition of the struct to better see how everything is used to better understand what is going wrong.

One thing that caught my attention is " getBudget". Either the extra space at the beginning is a typo or something else is wrong. Your error message should at least have given you a line number of the error so that you know where to look.

Hope that helps,

Andy
The first function code looks good and looks like it should work. Although I would suggest using "double"s over "float"s.


Yes it works fine, I’ll change it to double

I the third function You are passing in a struct, but never use it. There is nothing in the code that shows me that you are storing any information in the struct. And if the point of the function is to store information in the struct, what is the purpose of the return value?


I was hoping to be able to store the data in the struct so that I can print the struct out at the end of the program, but maybe it would be easier to just create the variable and cout it that way?

Your error message is lacking some information. Two functions use the variable "getBudget", so which function does the error message refer to?


To this one:
1
2
3
4
5
6
7
float myBudget(PersonalInfo &Budget, float car, float plane, float hotel)
{
	float getBudget = car + plane + hotel;
	cout << "Your Budget is: " << getBudget << ".";
	return getBudget;

}


One thing that caught my attention is " getBudget". Either the extra space at the beginning is a typo or something else is wrong. Your error message should at least have given you a line number of the error so that you know where to look.


It is a typo, that is my fault.

It would be helpful to see all of your code including the definition of the struct to better see how everything is used to better understand what is going wrong.


It’s not complete, I try to stop and test at certain areas to make sure it is working right before I move to the next step.


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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <iostream> 
#include <array>
#include <time.h> 
#include <string> 
#include <iomanip> 


using namespace std;


struct PersonalInfo
{
	string Name;
	int Age; 
	string locationName;
	int Budget_Amount;
};

const int personalCount = 4;
const int locationCount = 5;
const int ageCount = 4;

void getName(PersonalInfo &);
string myLocation(PersonalInfo &);
void getAge(PersonalInfo &);
//double myBudget(PersonalInfo &Budget, float car, float plane, float hotel);
double getBudget(float car, float plane, float hotel);

int main()
{
	
	array <PersonalInfo, personalCount> Traveler;
	array <PersonalInfo, locationCount> Location; 
	array <PersonalInfo, ageCount> Age;

	int adult_1_age, adult_2_age;
	int child_1_age, child_2_age;
	double budget = 0.0f;
	double car, plane, hotel;



	cout << "\n\t\t\t\t\t\t\t\t\t\t\t\t\t===============================\n";
	cout << "\n\t\t\t\t\t\t\t\t\t\t\t\t\t      Trip Planner             \n";
	cout << "\n\t\t\t\t\t\t\t\t\t\t\t\t\t===============================\n";

/*
	for (PersonalInfo &N : Traveler)
	{
		getName(N.Name);
	}

	for (PersonalInfo &A : Age)
	{
		getAge(A.Age);
	}

	for(PersonalInfo &L : Location)
	{
		myLocation(L.locationName);

	}
*/
	cout << "Would you need a rental car at your destination? \n[1] for yes or [2] for no: ";
	int answer;
	cin >> answer;
	if (answer == 1)
	{
		cout << "How much do you want to spend on your rental car?: ";
		cin >> car;

		if (answer == 2)
			cout << "A very heahlty choice!";
	}

	cout << "Are you going to fly? \n[1] for yes or [2] for no: ";
	int answer2;
	cin >> answer2;
	if (answer2 == 1)
	{
		cout << "How much do you want to spend on your rental car?: ";
		cin >> plane;

		if (answer == 2)
			cout << "Staying close to home are we?";
	}
	cout << "Are you going to need a hotel? \n[1] for yes or [2] for no: ";
	int answer3;
	cin >> answer3;
	if (answer3 == 1)
	{
		cout << "How much do you want to spend on your Hotel?: \n";
		cin >> hotel;

		if (answer3 == 2)
			cout << "I LOVE CAMPING CAN I COME TOO?\n";
	}
	cin.get();
	cout << "Your budget looks like this $" << getBudget(car, plane, hotel) << endl;
	//getBudget(car, plane, hotel);

	cin.get();
	return 0;
}


//Begin Functions
void getName(PersonalInfo &Explorer)
{
	cout << "What are your Names?: " << Explorer.Name;
	getline(cin, Explorer.Name);
}

void getAge(PersonalInfo &Age)
{
	cout << "What are the age of the travelers?: ";
	cin >> Age.Age;
}

string myLocation(PersonalInfo &Location)
{
	cout << "What are your location interest?: " << Location.locationName;
	getline(cin, Location.locationName);
}

double getBudget(float car, float plane, float hotel)
	{
	float budget = car + plane + hotel;
	return budget;
	}
/*
double myBudget(PersonalInfo &Budget)
{
	float getBudget = car + plane + hotel;
	return myBudget;
}*/


Last edited on
This looks very strange to me:
1
2
3
4
5
double myBudget(PersonalInfo &Budget)
{
	float getBudget = car + plane + hotel;
	return myBudget;
}

getBudget is another function, but you are redefining it as a float. And you are returning the address of the current function (myBudget). And you aren't using the parameter (Budget) at all.

Maybe you mean:
1
2
3
4
void myBudget(PersonalInfo &Budget)
{
	Budget.Budget_Amount = getBudget(car, plane, hotel);
}

Note that it doesn't return anything, but simply sets the Budget_Amount member of Budget to the return value of getBudget. Of course, Budget_Amount should be a double, not an int. (Unless you want to keep the money amount in cents as an int, which is often a good idea, but that's up to you.)
Hello SlowBug2319,

When I loaded up your program I found these problems:

1
2
3
4
int adult_1_age, adult_2_age;  // Unreferenced variables. Not used.
int child_1_age, child_2_age;  // Unreferenced variables. Not used.
double budget = 0.0;  // f not needed.
double car{ 0.0 }, plane{ 0.0 }, hotel{ 0.0 };  //  Needed initialized. 


And a problem with the for each loops:

Yours:
1
2
3
4
for (PersonalInfo &N : Traveler)
{
	getName(N.Name);
}

The concept works fine, but the implementation is wrong. The function "getName is defined as
void getName(PersonalInfo &Explorer) which is expeting a struct and you are sending the function a string. Changing to :

1
2
3
4
for (PersonalInfo &N : Traveler)
{
	getName(N);
}

Works and the same for the other two for each loops.

Then I realized that each array defined in main contain a total of 13 objects of the struct. Each having only one piece of information stored in the struct of each element of the array. This is a waste of storage space.

A better approach would be to create one array in main to hold individual structs if needed. And for the variables in the struct, "name", "age" and "locationName" make these arrays to hold more than one "name" etc. Or a vector would work even better changing size to hold however many names you need.

I was also thinking instead of the for each loops in main just call the functions for the input, put the for loop there and give the user a way out from entering names when they are finished instead of requiring four names or ages when only two are needed.

After that I have not spent much time on the rest of the program other than to see that it seems to work.

Hope that helps,

Andy
Hello SlowBug2319,

Looking at the rest of the program I noticed you define "answer", "answer2" and "answer3". Only "answer" is needed. Each question will have an input to "answer" and this will overwrite whatever is stored in the variable.

In your if statements you have:

1
2
3
4
5
6
7
8
if (answer == 1)
{
	cout << "How much do you want to spend on your rental car?: ";
	cin >> car;

	if (answer == 2)
		cout << "A very healthy choice!";  // FYI "heahlty" is misspelled.
}


Since the second if statement is within the closing brace of the first if statement it is never reached. You need to move the closing brace of the first if statement above the second if statement for it to work properly.

When everything was working I noticed that after all the work to fill the arrays you never use them. Unless the point was to work with functions.

Hope that helps,

Andy

P.S. Question 2 is the same as question 1.
Last edited on
Great idea and thank you so much Handy Andy!

Is there a preferred way to cin names into a vector, to avoiding memory leaks?
Is there a preferred way to cin names into a vector, to avoiding memory leaks?

Where do you think your getting a memory leak? Since you're not using manual memory management there there is little to no chance of memory leaks.

@jlb is right.
you're not using manual memory management
You are not using any "new", "malloc"... so you are not allocating space in the heap so there will not be memory leaks.
@SlowBug2319 Where do you want to declare the vector? How big do you expect the vector to be?
Last edited on
Hello puertas12,

Awe ok, I think I misunderstood or got somethings confused, thank you!

I liked Handy Andys suggestion, so this is how I decided to change it. I let the user decided how many instead of setting a limit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct PersonalInfo
{
	vector <string> name;
	vector <string> locationName;
	vector <double> budget;
};

void getNames()
{

for (int i = 1; i <= a; i++)
{
	
	cout << "What is their name?: " << endl;
       
        string a;
	getline(cin, a);
	PersonalInfo s;
	s.name.push_back(a);
}
}
You would be better off using a vector of your PersonalInfo class instead of a single instance of the class with all the vectors.
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
PersonalInfo
{
   PersonalInfo(const string& n, const string& location, double bud) :
                          name(n), locationName(location), budget(bud) {}
   string name;
   string locationName;
   double budget;
};

...
   vector<PersonalInfo> info;

   for(int i = 0; i < a; ++i) // Notice the normal zero based loop
   {
      string name, locationName;
      double budget;
      cout << "What is their name: ";
      getline(cin, name);
      cout << "What is the location: ";
      getline(cin, locationName);
      cout << "What is the budget: ";
      cin >> budget;
      cin.ignore(); // Get rid of the trailing end of line character.
      info.push_back({name, locationName, budget});
   }


Hello SlowBug2319,

A good start, but this is what I did:

PersonalInfo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _PERSONALINFO 
#define _PERSONALINFO

struct PersonalInfo
{
	std::vector<std::string> names;
	std::vector<int> Age;
	std::vector<std::string> locationName;
	double Budget_Amount;  // Should be a double. You only need one and not a vector,
};


#endif // end !_PERSONALINFO 

I made this its own file, but not necessary.

In the main file I redid the opening of main this 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
int main()
{
	PersonalInfo N;  // Needed for functions because the for loops are not needed.

	// these lines not needed now.
	//std::array <PersonalInfo, personalCount> Traveler;
	//std::array <PersonalInfo, locationCount> Location;
	//std::array <PersonalInfo, ageCount> Age;

	//int adult_1_age, adult_2_age;  // Unreferenced variables. Not used.
	//int child_1_age, child_2_age;  // Unreferenced variables. Not used.
	double budget = 0.0;  // f not needed.
	double car{ 0.0 }, plane{ 0.0 }, hotel{ 0.0 };  //  Needed initialized.

	getName(N);

	getAge(N);

        // Used after a "cin >>" and before a "std::getline". For your setup only needs to be used once here.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // Needs header file "limits"

	myLocation(N);

        // Rest of code. 


For the getName function
1
2
3
4
5
6
7
8
9
10
11
12
void getName(PersonalInfo &Explorer)
{
	std::string name{ "" };

	for (;;)  // <--- Endless loop or you could use "while (true)"
	{
		std::cout << "\nWhat are your Names? Enter to quit.: ";
		getline(std::cin, name);
		if (name == "") break;  //  Used to break out of loop
		Explorer.names.emplace_back(name);
	}
}


The "getAge" function is slightly different because of the "cin" and input being a number. The "myLocation" function is much the same as "getName". The endless loop allows the user to enter as little or as many names as needed.

At some point when you get a value for budget you should store this information in the struct. As your program is you only display the budget amount at the end of the program and "budget" in the struct goes unused.

Thinking to the future adding say a do/while loop to collect information for more than one person/trip then "budget " in the struct would have a use, Also you could add other variables to the struct for car, plane and hotel. This way you would have complete information for each person/trip.

Hope that helps,

Andy
Hello SlowBug2319,

With all the suggestions that have been made I looked at your OP (original post)
I am trying to make sure I understand functions
, so after all the changes to the program have we answered your question?

The changes to the program, as suggested, helps to make the functions work better and make more sense.

If you do not understand every thing you needed to let me know. May be a simple calculator program could do a better job learnig about functions.

Andy
Yes, and I have a lot better understanding of functions and vector. Thanks!
Topic archived. No new replies allowed.