So I'm trying to write a basic program in C++ to get the cost of something, the quantity, and calculate the total/subtotal, in three different functions, then display it in main().
Problem is, the variables aren't making it out of the function and I don't know why. I've put output statements inside the functions themselves to check, and the problem only seems to be when I'm trying to pull them out of said functions.
#include <iostream>
using namespace std;
int price(int cost)
{
cout << "What is the cost of the robot?" << endl;
cin >> cost;
if (cost < 1000) //validation
{
cout << "Cost is too low. Setting to $1000." << endl;
cost = 1000;
return cost;
}
return cost;
}
int numRobots(int number)
{
cout << "How many robots are being ordered?" << endl;
cin >> number;
if (number < 50) //validation
{
cout << "We only sell in quantities of 50 or more. Setting quantity to 50." << endl;
number = 50;
return number;
}
return number;
}
void grandTotal(int cost, int number, double &subtotal, double &total)
{
subtotal = (cost * number);
total = (subtotal * .07) + subtotal;
}
int main()
{
int cost = 0;
int number = 0;
double subtotal = 0;
double total = 0;
price(cost);`enter code here`
numRobots(number);
grandTotal(cost, number, subtotal, total);
cout << cost; //testing
cout << number; //outputs
cout << total; //of
cout << subtotal; //variables
system("pause");
return 0;
price(cost);
You are calling a function which returns an int, but you're not storing the int anywhere. You might want to go back to your text book and check the chapter on functions, and how they work. No offense but this is rather basic.
You're doing the same thing with numRobots.
Alternatively, you could pass the parameter by reference and modify it, but imo, that's less easy to understand.
tl;dr;
You should be doing int cost = price(); (there's no reason for the function to take an int as a parameter)
Use returned value or pass parameter by reference or pointer.
1.
int result = numRobots(number);
2.
int numRobots(int& number) {.....}
You need to pass the variables by reference:
int cost = 0;
int number = 0;
price(cost);
numRobots(number);
void price(int& cost)
{
....
}
void numRobots(int& number)
{
....
}
Note the void return type in this case!
Alternatively, you can utilize the return value:
int cost = price(cost);
int number = numRobots(number);
But this method doesn't make much sense because the variable passed as parameter to methods is the same as the one in which the return value is stored!
Related
I am trying to expand on previous code by implementing 2D-array's, however I keep getting issues with the console not outputting the correct values. The console is not taking in the right values when calculating the average and outputs 0 instead of the expected value. When running the code, the section where it would display the High and the Low scores would always display the first number that was typed in.
There are restrictions to work under.
Adjust the logic to drop the high score and the low score and average the remaining three scores for each student. The student grade is based on the average of the 3 middle scores.
All data is read in from the keyboard.
Two global constants may be utilized: one for the number of students and one for the number of tests.
Display in a table format the student's name, 5 test scores, average, and grade. Include a header in the table to label each column respectively.
Use iomanip and setw() to format the output.
Main should consist of variable declarations and function calls. This means the for loops to process the arrays resides in the functions, not in main.
Has to follow the base code.
`
using namespace std;
const int SCORES = 5;
const int NUM_STUDENTS = 3;
int main()
{
string name[NUM_STUDENTS];
int test[NUM_STUDENTS][SCORES];
char grade[NUM_STUDENTS];
float avg{};
int total = 0;
int hiIndex{}, loIndex{};
calcData(name, test, grade, total, hiIndex, loIndex, avg);
//display results
displayResults(name, test, grade, avg, loIndex, hiIndex);
system("pause");
return 0;
}
void calcData(string name[], int test[][SCORES], char grade[], int total, int hiIndex, int loIndex, float& avg)
{
for (int counter = 0; counter < NUM_STUDENTS; counter++)
{
getInput(name, test, counter, total);
cin.ignore();
//find index of the highest score and lowest score
findHiAndLow(test, hiIndex, loIndex, counter);
//assign letter grade
assignGrade(avg, grade, counter);
//calculate the class average
calcAvg(total - (test[counter][hiIndex] + test[counter][loIndex]), avg, SCORES - 2);
}
}
void getInput(string arrOne[], int arrTwo[][SCORES], int size, int& t)
{
//get student name
cout << "Input the student name and press enter\n";
getline(cin, arrOne[size]);
for (int i = 0; i < SCORES; i++)
{
//get student test score
cout << "Input the score for the midterm test\n";
cin >> arrTwo[size][i];
//(accumulate scores) total of all scores
t += arrTwo[size][i];
}
cout << endl;
}
int findHiAndLow(int t[][SCORES], int& h, int& l, int row)
{
for (int i = 0; i < SCORES; i++)
{
if (t[row][h] < t[row][i])
h = row;
if (t[row][l] > t[row][i])
l = row;
}
return h, l;
}
float calcAvg(int t, float a, int size)
{
a = static_cast<float>(t) / size;
return a;
}
void displayResults(string n[], int t[][SCORES], char g[], float a, int low, int high)
{
for (int counter = 0; counter < NUM_STUDENTS; counter++)
{
cout << left << setw(10) << n[counter] << ":";
for (int i = 0; i < SCORES; i++)
{
cout << setw(10) << t[counter][i];
}
cout << endl;
}
cout << "\n\nThe class average for this test = " << a << endl << endl;
for (int i = 0; i < NUM_STUDENTS; i++)
{
cout << n[i] << " your highest test score = " << t[i][high] << endl;
cout << n[i] << " your lowest test score = " << t[i][low] << endl << endl;
}
}
`
The expected outcome was for the program to take the average of the 3 middle scores that are left after dropping both the high and low scores from the initial 5 scores that are given. I have tried rearranging the values in both findHiandLow() and getInput(). I have tried having both for loops for getInput() within the function and have switched back to having one on the outside (within calcData()) to include the other functions, with the intent of having it loop for each student.
I wanted the console to print out the average of the three middle scores and not include the High and low, I was also expecting the console to print out the High and low scores for the student but it only prints the first score.
If my numbers were, for example, 12, 89, 45, 100, 23; The expectation would've been that it would drop the 12 and 100 and leave me with 89, 45, and 23. It would then take the average of those 3 numbers which in theory should result in 52.34 and result in an "F", however it prints out 0. and because the number that was first typed in was 12 the lowest and highest number would be listed as 12. It should have been 12 and 100 respectively.
This is another case of the incredibly common newbie confusion over returning values from functions.
This is your function
float calcAvg(int t, float a, int size)
{
a = static_cast<float>(t) / size;
return a;
}
You are trying to calculate the average and return the result, but for some reason you have declared a as a parameter, instead of as a local variable. This is how it should look
float calcAvg(int t, int size)
{
float a = static_cast<float>(t) / size;
return a;
}
Once you see that you should see that it can be further simplified, eliminating a altogether
float calcAvg(int t, int size)
{
return static_cast<float>(t) / size;
}
Now look at how you call calcAvg.
calcAvg(total - (test[counter][hiIndex] + test[counter][loIndex]),
avg, SCORES - 2);
you are calling the function, but doing nothing with the returned value. This is how it should look
avg = calcAvg(total - (test[counter][hiIndex] + test[counter][loIndex]),
SCORES - 2);
Now the return value of calcAvg is being assigned to the variable avg changing it's value. This is clearly what you intended. If you want to change the value of a variable using a functions return value the syntax is x = func(); not func(x).
Really not sure why this is such a stumbling block for newbies. The correct code has always seemed natural and straightforward to me. But, in any case, remember that parameters and return values are different things, with different syntax, and different purposes.
Can someone give advice or guidance on what is wrong with my program? I do have the program fully written out, I am not sure where to add the function definition and function prototype to my program. This program involves pass by value and pass by reference. Also, any helpful notices on small errors will be appreciated
#include "pch.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
//Declare Variables
double amount = 22.66;
int num;
int dollars;
int quarters;
int dimes;
int nickels;
int pennies;
double x = 22.25;
double y = 55.55;
//Input
cout << "Please enter your dollar amount: ";
cin >> amount;
void showMenu() //function prototype
{
cout << "A. Money Exchange function" << endl;
cout << "B. Find Max Solution" << endl;
cout << "E. Exit" << endl;
cout <<"Please enter your choice:"<<endl;
}
void MoneyExchange(float amount, int& dollars, int& quarters, int& dimes,
int & nickels, int & pennies) // function prototype
{
int amount = 0, Remainder;
amount = amount * 100;
dollars = amount / 100;
Remainder = amount - (dollars * 100);
quarters = Remainder / 25;
Remainder = Remainder - (quarters * 25);
dimes = Remainder / 10;
Remainder = Remainder - (dimes * 10);
nickels = Remainder / 5;
Remainder = Remainder - (nickels * 5);
pennies = Remainder / 1;
}
double max(double x, double y) //function prototype
{
double max;
if (x >= y)
max = x;
else
max = y;
system("Pause");
return 0;
}
To use a function, you need to have a function method declaration (tell compiler/linker that this function exists) and implementation (stuff that function method does).
Here is a barebones example
void doStuff(); //im function declaration/prototype
void doMoreStuff(); //im function declaration/prototype
int main()
{
void doMoreStuff() //dont nest me in here!
{
cout << "doMoreStufff runs" << endl;
}
doStuff();
doMoreStuff();
return 1;
}
void doStuff() //im function implementation
{
cout << "doStuff runs" << endl;
}
Key take aways:
1) What you call a function prototype in your code is function implementation
2) No nesting implementation. for example: Dont do this
int main()
{
void doMoreStuff() //dont nest me in here!
{
cout << "doMoreStufff runs" << endl;
}
doStuff();
doMoreStuff();
return 1;
}
void doStuff() //im function implementation
{
cout << "doStuff runs" << endl;
}
(side note: one could nest anonymous/lambda functions inside)
3) In your case it doesnt matter if you stick method implementation above or below main{} implementation, just make sure you have your functions declared above main{} implementation (where these methods are used)
TLDR Poor naming conventions, not prototyping/declaring and defining properly, mismatched variable types, hiding value of amount (22.66, then cin, then int amount = 0 in MoneyExchange), unused code (max function), menu is not functional.
You are trying to define functions inside the main function like such:
int main() {
// ...
void showMenu() {
// code to do stuff
}
// ...
return 0;
}
It does not work like this. If you want to define and declare showMenu, so it can be used in main, try this. (See above)
void showMenu() {
// code to do stuff
}
int main() {
// ...
showMenu();
// ...
}
If you do not prototype the function, you must declare it above the main function. Otherwise it won't compile. (See above)
Try this (See below) if you want to prototype. You can have your prototypes in the main file or in a header file which you can include in main.
void showMenu(); // prototype
int main() {
// ...
showMenu();
// ...
}
void showMenu() {
// code to show the menu
}
If you want to define a function inside another, you should use a lambda expression.
Problems with your program:
-You define amount as a double of value 22.66 and then write over it when you cin >> amount. You only need to set the value once, so remove the cin or (preferably) change it to
double amount;
-Your functions and procedures, showMenu, MoneyExchange and max need to be moved outside of main, and prototyped or defined before main.
-You should find a naming convention which works for you and stick to it. You have procedure names starting with a capital MoneyExchange and then one starting with lower case, showMenu. Stick to the same, I'd use moneyExchange and showMenu.
You have done the same thing with variables, have a look here https://code.tutsplus.com/articles/9-confusing-naming-conventions-for-beginners--net-15584 this explains some naming conventions.
-Max function does not return anything. It must return a double, as you've declared. E.G.
double max(double x, double y) {
// ...
return 0.0;
}
-In MoneyExchange you declare a new int called amount, which you have declared locally in main as a double. You also set the value to 0, not the amount you inputted using cin.
-When you declare MoneyExchange, amount is taken as a float. So you pass a double, receive it as a float and then make a new int called amount... Stick to one data type. You also don't pass it by reference.
-You don't use the max function anywhere in this code.
-You don't get input from the menu, so the user does not have an option. I would use a switch statement. See this link http://www.cplusplus.com/forum/general/156582/ .
Student here. I'm missing a single rubric item in the following project program and can't figure out where to place it, "it" being a pass-by-reference item. If anyone is feeling generous, please take a look at my program below and give me a heads-up about where I could tweak the code to make pass-by-reference possible. As it stands, I'm stumped and I don't have enough time to come up with an entirely new problem for which to code a solution. Thank you all in advance!
#include <iostream>
#include <cmath>
using namespace std;
//Global Variable
int height = 0;
//Function Prototypes
int getMale();
int getFemale();
int main()
{
//Local Variable
int ideal = 0;
char sex(' ');
//Sequence Structure
cout << "Welcome to the Hamwi Ideal Body Weight Equation Calculator!" << endl;
cout << "Please enter your height in inches (remember, 1 foot = 12 inches): " << endl;
cin >> height;
cout << "Please enter your biological sex (M or F): " << endl;
cin >> sex;
//Repetition Structure
while (toupper(sex) != 'M' && 'F')
{
cout << "Invalid entry. Please enter your biological sex (M or F): " << endl;
cin >> sex;
} //end while
//Selection Structure
if (toupper(sex) == 'M')
{
int ideal = getMale();
cout << "Thank you. Your ideal body weight is approximately: " << ideal << " pounds." << endl;
cout << "Have a nice day!" << endl;
} //end if
else
{
int ideal = getFemale();
cout << "Thank you. Your ideal body weight is approximately: " << ideal << " pounds." << endl;
cout << "Have a nice day!" << endl;
} //end else
return 0;
} //end of main function
//Program-Defined Function #1 (Male)
int getMale()
{
//Local Variable
int male = 0;
if (height >= 60)
{
male = 106 + ((height - 60) * 6);
return male;
} //end if
else
{
male = 106 - ((60 - height) * 6);
return male;
} //end else
} //end of male function
//Program-Defined Function #2 (Female)
int getFemale()
{
//Local Variable
int female = 0;
if (height >= 60)
{
female = 100 + ((height - 60) * 5);
return female;
} //end if
else
{
female = 100 - ((60 - height) * 5);
return female;
} //end else
} //end of female function
Declare your two functions like this
int getMale ( int& height );
int getFemale ( int& height );
And in your main you declare a variable that you can pass to the functions
int main()
{
// Declare here instead of globally
int height = 0;
// Then you can call
int result = getMale(height);
result = getFemale(height);
}
It will behave the same way. It is considered better practice to pass by reference than to use a global variable, so kudos to you for asking this question.
You pass height by reference in one of your gender functions.
For example:
int getMale(int &height) {
/* do stuff */
}
And then simply call it by:
getMale(height);
Also, are you required go use a global variable? If not, then make height a local variable in your main as other commenters have stated. Global variables are considered bad style, as they can cause hard-to-diagnose problems when you're working on a much larger project.
You could move variable height to main() (make it local) and pass it by reference to all your functions. Actually, I'd say that would be a better style than passing data through global variables.
But in a real project it's typically better to think of what behavior you want from your program, not of what awesome language features you want to use.
Is this program not giving you the correct answer and that's why you want to pass by reference? or what is the exact situation?
Anyways in order for you to pass by reference then you remove height from being a global variable and have it local in your main, then for your prototypes include a reference parameter then when you call them in main pass your local variable.
This is example of how pass by reference would work.
#include<iostream>
using namespace std;
//Prototype
void add(int num1, int num2, int &res);
int main()
{
int res;
add(1, 2, res);
cout<<"I got the value by passing my variable by reference"<<res<<endl;
return 0;
}
void add(int num1, int num2, int &res)
{
res = num1 + num2;
}
I'm trying to the program to display the bonus, but the programs renders an answer to 0. I am extremely new to c++ so any guidance would be greatly appreciated.
Here's the code:
#include <iostream>
#include <iomanip>
using namespace std;
//function prototypes
void enterItems(double, double);
void calcAndDisplayBonus(double &salesAmt, double &rate);
int main()
{
//declare variables
double sales = 0.0;
double bonusRate = 0.0;
//enter input values
enterItems(sales, bonusRate);
//calculate and display bonus
cout << fixed << setprecision(2);
calcAndDisplayBonus(sales, bonusRate);
system("pause");
return 0;
} //end of main function
//*****function definitions*****
void enterItems(double salesAmt, double rate)
{
cout << "Enter sales: ";
cin >> salesAmt;
cout << "Enter bonus rate (in decimal form): ";
cin >> rate;
} //end of enterItems function
void calcAndDisplayBonus(double &salesAmt, double &rate)
{
cout << "Bonus: $" << salesAmt * rate << endl;
} //end of calcAndDisplayBonus function
When you call enterItems, you are passing parameters by copy. This means that your changes won't affect the variables available in the scope of the caller.
To solve it, you can either pass a couple of references or pointers, as well as rely on a pair returned from the function as a result, and so on.
As an example, by writing:
void enterItems(double &salesAmt, double &rate)
You'll actually solve the problem above mentioned.
Another valid prototype is:
void enterItems(double *salesAmt, double *rate)
Even though this one asks for a small set of changes all around your code (the example, of course).
There is a plenty of possible solutions, hoping these ones will give you an idea of what's wrong.
Your function
void enterItems(double salesAmt, double rate)
is taking two double-parameters by value, this means, your changes you do inside the function will not be visible from the outside. You could take the doubles by reference:
void enterItems(double &salesAmt, double &rate)
but i'd prefer to return the values, but since you can only return a single value you'd need two functions:
double enterSales()
{
double tmp;
cout << "Enter sales: ";
cin >> tmp;
return tmp;
}
double enterBonus()
{
double tmp;
cout << "Enter bonus rate (in decimal form): ";
cin >> tmp;
return tmp;
}
//in your main:
double sales = enterSales();
double bonusRate = enterBonus();
There is a problem with the code and i could not find it.
i was asked to write a money struct and use functions to manipulate it.
but the code did not work for any function. i tried couting
the array of structers and it came out nicely, for any missing info
please leave a comment and i'll reply shortly.
Money.txt
2
12 20
13 40
#include <iostream>
#include <fstream>
using namespace std;
struct Money { //declaring structure
int dollars;
int cents;
};
Money addMoney(Money *p[], int n) { //adds money data
Money cash{ 0,0 };
int i;
for (int j = 0; j < n; j++) {
cash.dollars = cash.dollars + p[j]->dollars;
cash.cents = cash.cents + p[j]->cents;
}
if (cash.cents >= 100) //100cents = 1 dollar
{
i = (cash.cents) / 100;
cash.dollars = cash.dollars + i;
i = (cash.cents) % 100;
cash.cents = i;
}
return cash;
}
void printMoney(Money *p[], int n) { //printing money data
for (int i = 0; i < n; i++) {
cout << "Dollars: " << p[i]->dollars << endl;
cout << "Cents: " << p[i]->cents << endl;
}
}
Money maxMoney(Money *p[], int n) {
Money cash;
cash.dollars = p[0]->dollars;
cash.cents = p[0]->cents;
for (int i = 0; i < n; i++)
{
if ((p[i]->dollars)>=(cash.dollars))
if ((p[i]->cents)>(cash.cents))
{
cash.dollars = p[i]->dollars;
cash.cents = p[i]->cents;
}
}
return cash;
}
void main() {
Money cash;
ifstream mycin("money.txt");
if (mycin.fail())
cout << "Enable to open file";
int x;
mycin >> x;
Money *arr = new Money[x];
for (int i = 0; i < x; i++)
{
mycin >> arr[i].dollars;
mycin >> arr[i].cents;
}
cout << "The values in money.txt are: ";
printMoney(&arr, x);
cash = addMoney(&arr, x);
cout << "These values added are :";
cout << cash.dollars << " Dollars and " << cash.cents << " cents" << endl;
cash = maxMoney(&arr, x);
cout << "Maximum value is :";
cout << cash.dollars << " Dollars and " << cash.cents << " cents" << endl;
}
These functions appear to accept an array of pointers to Money, but you're trying to use them with an array of Money.
I suggest you play with arrays of pointers to simpler types (like int) until you're comfortable with the concept, before you attempt it with Money.
This sounds a lot like homework so I'm not posting a full solution, but I will explain what appears to be the misunderstanding and give you some pointers.
First you declare your data structure as an array of Money structures, e.g. a continuous series of blocks of memory containing the Money struct, the first of which is pointed to by "arr" in your main program.
But then, in the rest of the program (functions) you seem to expect the data structure being used to be an array of Money pointers. See the difference? They're not the same and this will not work as is. You have to be consistent.
Either you're dealing with an array of structs, in which case you pass effectively a single, simple Money* to your functions everywhere (and you dereference with . not ->)
Or you're dealing with an array of pointers, in which case you pass effectively a pointer to a (Money pointer) and you dereference with -> as you've done. But then you also have to allocate each Money struct individually when you're reading them in in the main program. That is to say, allocating memory for the array of pointers does not automatically allocate memory for each Money pointer reference in the array of pointers and so you need to do this for each entry you're reading in.
So, as you should hopefully now realise, there's multiple ways to fix your program.
As per your later comment, given that the function signatures need to stay as-is, I would suggest you work with an array of Money pointers.
Money** arr = new Money*[x]
Then you need to add a line to your loop during reading, to actually make each Money * point to a Money struct:
for (int i = 0; i < x; i++)
{
arr[i] = new Money
...
Finally then, because "arr" is now a pointer to a pointer to Money, you can directly pass it to your functions, so calling them are just for example:
printMoney(arr, x);