I seem to be having trouble with passing variables from one function to another. My main class looks like this :
class EmployeeClass {
public:
void ImplementCalculations(string EmployeeName, double hours, double wage);
void DisplayEmployeeInformation();
void Addsomethingup (EmployeeClass, EmployeeClass, EmployeeClass);
string EmployeeName;
double hours;
double wage;
double basepay;
double overtime_hours;
double overtime_pay ;
double overtime_extra ;
double iTotal_salaries ;
double iIndividualSalary;
double iTotal_hours ;
double iTotal_OvertimeHours;
};
I am passing a string and two doubles to the function "ImplementCalculations" as shown here:
Employee1.ImplementCalculations (Employee1.EmployeeName, Employee1.hours, Employee1.wage);
Employee2.ImplementCalculations (Employee2.EmployeeName, Employee2.hours, Employee2.wage);
Employee3.ImplementCalculations (Employee3.EmployeeName, Employee3.hours, Employee3.wage);
These passed variables have some math done to them:
void EmployeeClass::ImplementCalculations (string EmployeeName, double hours, double wage) {
//Initialize overtime variables
double overtime_hours=0;
double overtime_pay=0;
double overtime_extra=0;
double basepay = 0;
double iIndividualSalary = 0;
if (hours > 40)
{
basepay = 40 * wage;
overtime_hours = hours - 40;
overtime_pay = wage * 1.5;
overtime_extra = overtime_hours * overtime_pay;
iIndividualSalary = overtime_extra + basepay;
/*
Implement function call to output the employee information. Function is defined below.
*/
DisplayEmployeeInformation ();
} // if (hours <= 40)
else
{
basepay = hours * wage;
overtime_hours=0;
overtime_extra=0;
iIndividualSalary = basepay;
/*
Implement function call to output the employee information. Function is defined below.
*/
DisplayEmployeeInformation();
}; // End of the else
However this is where things go sour. I think that because I am not passing DisplayEmployeeInformation anything it doesn't want to work, which also makes it so that AddSomethingUp doesn't work as well.
void EmployeeClass::DisplayEmployeeInformation () {
// This function displays all the employee output information.
cout << "Employee Name ............. = " << EmployeeName << endl;
cout << "Base Pay .................. = " << setprecision(5)<< basepay << endl;
cout << "Hours in Overtime ......... = " << setprecision(4)<< overtime_hours << endl;
cout << "Overtime Pay Amount........ = " << setprecision(5)<< overtime_pay << endl;
cout << "Total Pay ................. = " << setprecision(6)<< iIndividualSalary << endl;
} // END OF Display Employee Information
void EmployeeClass::Addsomethingup (EmployeeClass Employee1, EmployeeClass Employee2, EmployeeClass Employee3){
/*
Adds the total hours for objects 1, 2, and 3.
Adds the salaries for each object.
Adds the total overtime hours.
*/
iTotal_hours = Employee1.hours + Employee2.hours + Employee3.hours;
iTotal_salaries = Employee1.iIndividualSalary + Employee2.iIndividualSalary + Employee3.iIndividualSalary;
iTotal_OvertimeHours = Employee1.overtime_hours + Employee2.overtime_hours + Employee3.overtime_hours;
cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
cout << "%%%% EMPLOYEE SUMMARY DATA%%%%%%%%%%%%%%%%%%%%%%%" << endl;
cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
cout << "%%%% Total Employee Salaries ..... = " << setprecision(6)<<iTotal_salaries <<endl;
cout << "%%%% Total Employee Hours ........ = " << setprecision(5)<<iTotal_hours << endl;
cout << "%%%% Total Overtime Hours......... = " << setprecision(5)<<iTotal_OvertimeHours << endl;
cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
} // End of function
The one line in AddSomethingUp that works is the iTotal_hours. No idea why it gets that, but it is the only thing it gets.
So my question is do I have to pass DisplayEmployeeInformation some sort of variables? What should that look like? More like passing the information to ImplementCalculations?
EmployeeClass has a number of member variables such as: hours, overtime_hours and others.
The ImplementCalculations function declares a bunch of local variables right at the start with the exact same name. It also has parameters with the exact same name.
I assume that in the start of ImplementCalculations you don't wish to declare new variables but rather set the values for the ones in the class:
void EmployeeClass::ImplementCalculations (string EmployeeName, double hours, double wage) {
//Initialize overtime variables
overtime_hours=0;
overtime_pay=0;
overtime_extra=0;
basepay = 0;
iIndividualSalary = 0;
... (other code here) ...
Also consider renaming the parameter variables to something like p_EmployeeName and p_hours (etc) so they don't clash with the member variable names in your class.
While it is not 100% clear what your problem is, it is very likely that the cause of it is the fact that you are not using references.
For example, take this function:
void Addsomethingup (EmployeeClass Employee1);
This creates a copy of Employee1, which is thrown away when the function is left. The original object which you pass into the function is not touched and remains the same.
You might try this:
void Addsomethingup (EmployeeClass &Employee1);
You can also pass const references as an alternative to useless copying if you don't intend to modify the object:
void Addsomethingup (EmployeeClass const &Employee1);
In fact, you should do so for your std::string arguments (although C++11 may be kind of a game changer here, but you better consult Google for this, or else it becomes too off-topic for this question). And you probably need to read a good C++ book. References are a pretty basic language feature.
If you come from a Java background, don't be confused by the word "reference". A "reference" in Java is more a like a pointer in C++, whereas C++ references do not have a Java counterpart.
Related
Working on an assignment about Abstract Base classes, I'm running into a segment fault when I execute the getInput function I created in the addRecord function. I've tried a variety of methods for getting the user input for the name of the Employee/Student, however I keep running into issues with it.
getInput:
char* getInput(std::string message)
{
char* name;
std::cout << message << std::endl;
std::cin.ignore(INT_MAX, '\n');
std::cin.getline(name, INT_MAX);
return name;
}
addRecord:
/*
* addRecord(vecotr<base*>& v)
*
* Ask the user which type of record they want to add, an employee or student. Once
* they have made their selection, dynamically create a new pointer of the selected
* type of record and have them fill out the record's members via its set methods,
* then add it to the vector using the vector method .push_back().
*/
void addRecord(std::vector<Base*>& v)
{
std::cout << "--Records to Create--" << std::endl;
std::cout << "1.) Student Record" << std::endl;
std::cout << "2.) Employee Record" << std::endl;
std::cout << "Please select from the above options: ";
int sel = intInputLoop(1, 2);
clearConsole();
if (sel == 1)
{
char* name;
/*
std::cout << "Record Type: Student" << std::endl;
std::cin.ignore(INT_MAX, '\n');
std::cin.getline(name, INT_MAX);
*/
name = getInput("What is the Student's name? ");
float gradePointAverage = (float)intInputLoop(0, 4);
Student student = Student();
student.setName(name);
student.setGradePointAverage(gradePointAverage);
Base* bp = &student;
v.push_back(bp);
std::cout << "Added Student record for " << name << " with a grade point average of " << gradePointAverage << std::endl;
delete name;
}
else
{
char* name;
std::cout << "Record Type: Employee" << std::endl;
name = getInput("What is the Employee's name? ");
std::cout << "What is the Employee's salary? ";
int salary = intInputLoop(0, 0);
Employee employee = Employee();
employee.setName(name);
employee.setSalary(salary);
Base* bp = &employee;
v.push_back(bp);
std::cout << "Added Employee record for " << name << " with a salary of " << salary << std::endl;
delete name;
}
}
Any input is much appreciated. Thank you in advance.
char* name;
This declares a pointer, to an indeterminate number of char values. Who knows how many of them there are. It could be just one, very lonely char, sitting there, all by itself with nobody to play with. It could be a million, an entire city of chars. It's completely unspecified, nobody knows; that's because the pointer is completely uninitialized. Nothing in C++ happens automatically. If you intend to use a pointer, it must, well, point somewhere valid before you can use that pointer.
std::cin.getline(name, INT_MAX);
This call to getline reads input into a pointer. The pointer must point to valid memory. Since the pointer is uninitialized, this is undefined behavior, and is the reason for your crash.
Since your intent here is to use C++, the simplest solution is to use a C++ class that just happens to handle all the memory management for you: std::string:
std::string name;
std::getline(std::cin, name);
You'll need to replace all old-fashioned char * pointers, which is what you would use if you were writing C code, with std::string. After all: this is C++, not C.
This question already has answers here:
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Closed 1 year ago.
Background: So I basically googled projects for beginners for C++ and one recommendation was currency converter. So I decided to do this, at first I tried to do it by creating a class, objects etc but I got lost with constructors and header files etc but that's a story for another day. I am very new to programming and this is my first "project".
So I decided to go the simple route and did this:
#include <iostream>
int main(){
double euro;
//creating all the variables and conversions
double eur2dol = euro * 1.13;
double eur2pound = euro * 0.84;
double eur2rup = euro * 84.49;
double eur2yuan = euro * 7.2322769;
double eur2btc = euro * 0.0000237;
double eur2eth = euro * 0.00029956;
// creating an array with the name of the currency i am converting to
std::string curname[6] = { " Dollars\n", " Pounds\n", " Rupees\n", " Yuan\n", " Bitcoin\n", " Etherium\n"};
// creating an array with the conversions i want to do
double currencies[6] = { eur2dol, eur2pound, eur2rup, eur2yuan, eur2btc, eur2eth };
//accepting input from the user
std::cout << "Amount in euros: " << std::endl;
std::cin >> euro;
// for loop to loop through every item in the currencies array and the corresponding name of the currency from the curname array
for(int i = 0; i < 5; i++){
std::cout << euro << " Euro is " << currencies[i] << curname[i];
};
return 0;
}
Now, I know there is no point in doing this other than practicing because the values constantly change but I am getting the same result no matter the value I type in and in scientific form.
How can I fix it so i get the correct result and what is the problem?
A typical case of uninitialized variable. Here you are operating on euro variable before asking(cin) value for it, The correct implementation would be something like:
#include <iostream>
int main()
{
double euro = 0; //always put some values beforehand
//accepting input from the user
std::cout << "Amount in euros: " << std::endl;
std::cin >> euro;
//creating all the variables and conversions
double eur2dol = euro * 1.13;
double eur2pound = euro * 0.84;
double eur2rup = euro * 84.49;
double eur2yuan = euro * 7.2322769;
double eur2btc = euro * 0.0000237;
double eur2eth = euro * 0.00029956;
// creating an array with the name of the currency i am converting to
std::string curname[6] = { " Dollars\n", " Pounds\n", " Rupees\n", " Yuan\n", " Bitcoin\n", " Etherium\n"};
// creating an array with the conversions i want to do
double currencies[6] = { eur2dol, eur2pound, eur2rup, eur2yuan, eur2btc, eur2eth };
// for loop to loop through every item in the currencies array and the corresponding name of the currency from the curname array
for(int i = 0; i < 5; i++){
std::cout << euro << " Euro is " << currencies[i] << curname[i];
};
return 0;
}
Note: Uninitiazed variable is a bad practice. If you initialized the variable like double euro = 0; earlier, it will alteast not return arbitrary values even for the wrong code.
You can format your floating-point values with std::fixed and std::setprecision.
Apart from that:
Make sure you don't use euro before reading it.
Try and declare the variables as close to the place where you first use them as possible.
currencies array would probably better be called conversion_rates or something like that.
[Demo]
#include <iomanip> // setprecision
#include <ios> // fixed
#include <iostream>
int main() {
// creating all the variables and conversions
double eur2dol = 1.13;
double eur2pound = 0.84;
double eur2rup = 84.49;
double eur2yuan = 7.2322769;
double eur2btc = 0.0000237;
double eur2eth = 0.00029956;
// creating an array with the name of the currency i am converting to
std::string currency_name[6] = { "Dollar", "Pound", "Rupee", "Yuan", "Bitcoin", "Etherium" };
// creating an array with the conversions i want to do
double conversion_rates[6] = { eur2dol, eur2pound, eur2rup, eur2yuan, eur2btc, eur2eth };
// accepting input from the user
std::cout << "Amount in euros: " << std::endl;
double euro{};
std::cin >> euro;
// for loop to loop through every item in the currencies array and
// the corresponding name of the currency from the curname array
for (int i = 0; i < 6; i++) {
std::cout << std::fixed << std::setprecision(2) << euro << " Euro is "
<< std::setprecision(5) << euro * conversion_rates[i] << " " << currency_name[i] << "\n";
};
return 0;
}
You could as well slightly improve your solution and get started with concepts such as structs and STL containers just by:
defining a Currency struct, where you hold the the currency name and rate conversion from euros,
using a constant vector of currencies,
walking the vector with a range for loop.
[Demo]
#include <iomanip> // setprecision
#include <ios> // fixed
#include <iostream> // cout
#include <string>
#include <vector>
struct Currency
{
std::string name{};
double from_euro_rate{};
};
int main() {
const std::vector<Currency> currencies{
{"Dollar", 1.13},
{"Pound", 0.84},
{"Rupee", 84.49},
{"Yuan", 7.2322769},
{"Bitcoin", 0.0000237},
{"Etherium", 0.00029956}
};
// accepting input from the user
std::cout << "Amount in euros: ";
double euro{};
std::cin >> euro;
std::cout << euro << "\n\n";
// for loop to loop through every item in the currencies array and
// the corresponding name of the currency from the curname array
for (auto& currency : currencies) {
std::cout << std::fixed << std::setprecision(2) << euro << " Euro is "
<< std::setprecision(5) << euro * currency.from_euro_rate << " " << currency.name << "\n";
};
}
[Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11
Below I have used // to show that three lines of code where I got the error, despite the code working fine.
#include <iostream>
#include <conio.h>
using namespace std;
class Bank
{
private:
char name[20];
int accNo;
char x;
double balance;
double amount;
float interestRate;
float servCharge = 5; //[Warning]
float count = 0; //[Warning]
bool status = true; //[Warning]
public:
void openAccount();
void depositMoney();
void withdrawMoney();
void checkBalance_info();
void calcInt();
void monthlyProc();
};
void Bank::calcInt() {
cout << " Enter your annual interestRate : " << endl;
cin >> interestRate;
double monthlyInterestRate = interestRate / 12;
double monthlyInterest = balance * monthlyInterestRate;
balance += monthlyInterest;
cout << "Updated Balance After Monthly interestRate " << balance << endl;
if (balance < 25){
status = true;
}
void Bank :: monthlyProc(){
if (balance < 25){
status = false;
}
while (count > 4){
balance = balance - 1;
}
servCharge = servCharge + (count * 0.10);
balance -= servCharge;
cout << "Monthly Service Charges: " << servCharge <<endl;
cout << "Updated Balance After Monthly interestRate " << balance << endl;
}
Also, I did not include the whole code cause it is a bit longer. Please tell me if I need to upload the whole code. Just need help to make the code run without any sort of error.
float servCharge = 5; //[Warning]
float count = 0;//[Warning]
bool status = true;//[Warning]
Those are warnings, not errors. It means that you are initialising those member variables in-class but those are not static members. This was a limitation of older C++98 and C++03.
You may eliminate those warnings in two ways:
(1) Do exactly what the compiler wants you to do, ie specifying these option when compiling your code:
-std=c++11 or -std=gnu++11 // using newer C++11
(2) Do initialise those in-class definition, instead using initialising them using the old way ie. using the constructor:
Bank::Bank() : servCharge(5), count(0), status(true)
{
//..
}
I have an structure named "Particle" and I want to create several objects whose names depends on an int.
As I am inside a for loop the name is going to change as follows: part0, part1, part2.
for (int i = 0; i<num_particles; i++)
{
//double sample_x, sample_y, sample_theta;
string name = "part" + std::to_string(i);
Particle name;
name.id = i;
name.x = dist_x(gen);
name.y = dist_y(gen);
name.theta = dist_theta(gen);
cout << "Sample" << " " << name.x << " " << name.y << " " << name.theta << endl;
}
As you can imagine this approach doesn't work, do you have any solution?
I have updated my question, now this is my new approach:
I have created a vector and an int "number of particles":
std::vector<Particle> particles;
And the function code:
void ParticleFilter::init(double x, double y, double theta, double std[]) {
// TODO: Set the number of particles. Initialize all particles to first position (based on estimates of
// x, y, theta and their uncertainties from GPS) and all weights to 1.
// Add random Gaussian noise to each particle.
// NOTE: Consult particle_filter.h for more information about this method (and others in this file).
default_random_engine gen;
normal_distribution<double> dist_x(x, std[0]);
normal_distribution<double> dist_y(y, std[1]);
normal_distribution<double> dist_theta(theta, std[2]);
//for (int i = 0; i<num_particles; i++)
//{
//double sample_x, sample_y, sample_theta;
//string name = "part";
//+ std::to_string(i);
//Particle particles;
particles[num_particles].id =num_particles;
particles[num_particles].x = dist_x(gen);
particles[num_particles].y = dist_y(gen);
particles[num_particles].theta = dist_theta(gen);
num_particles++;
cout << "Sample" << " " << particles[num_particles].x << " " << particles[num_particles].y << " " << particles[num_particles].theta << endl;
//}
}
But it doesn't work yet, it outputs "Segmentation fault".
you can use itoa() function of cstdlib simply in your code.
for (int i = 0; i<10; i++)
{
char a[max];
string pa="part_";
string name = pa + itoa(i,a,i+1) ;
cout << "Sample" << " " << name << endl;
}
}
Sample Output:
Sample part_0
Sample part_1
Sample part_2
Sample part_3
Sample part_4
Sample part_5
Sample part_6
Sample part_7
Sample part_8
Sample part_9
This construct exists in C++, it is called std::vector.
// we want to have a bunch of variables of type Particle
// all named particles[i] for i == 0,1,2....
std::vector<Particle> particles;
// create a new particle variable
particles.emplace_back(x, y, theta);
// print the variable number 42
std::cout << particles[42];
Why do you want to down the messy road of variable naming such as var0, var1, var2 and so on? I'd recommend creating an array or vector.
It's not clear from your code snippet that why you need to create variables with different names. Moreover, your code/usecase doesn't sit right with the concept of variable scoping.
I am new to C++. I am struggling with the pass by value thing, and no one can explain what I am doing wrong to me in a way I can understand. I know this is my fault, but Ii am asking for help with my code. HELP PLEASE!
#include <iostream>
using namespace std;
double getValues();
double getSalesTax(double SalesTaxPct);
double gettotal_price(double base, double opt);
void PrintFinal(double base,double opt,double SalesTaxPct);
// function to control all other functions
int main()
{
getValues();
getSalesTax(SalesTaxPct);
PrintFinal(base,pt,SalesTaxPct);
}
// function to calculate sales tax percent into decimal
double getSalesTax( double SalesTaxPct )
{
double SalesTax;
SalesTax = SalesTaxPct / 100;
return SalesTax;
}
// function to find total
double gettotal_price(double base, double opt, double SalesTax)
{
return = (base + opt) * (1 + SalesTax);
}
// function to show user all values input and also total
void PrintFinal(double base, double opt, double SalesTaxPct)
{
cout << "Base vehicle price: $" << base << endl;
cout << "Options Price: $" << opt << endl;
cout << "Sales tax pct: " << SalesTaxPct << "%" << endl;
cout << "Total vehicle price: $" << gettotal_price(double base, double opt, double SalesTax) << endl;
}
// function to get input values
void getValues()
{
double base, double opt, double SalesTaxPct;
cout << "Enter a base vehicle price: " << endl;
cin >> base;
cout << "Enter options price: " << endl;
cin >> opt;
cout << "Enter a sales tax percent: " << endl;
cin >> SalesTaxPct;
}
When you are in main, let's go over what the program sees:
int main()
{
getValues();
getSalesTax(SalesTaxPct);
PrintFinal(base,pt,SalesTaxPct);
}
The only variables that your program knows about at this point are: getValues(), getSalesTax(), gettotal_price(), and PrintFinal(). The warning is telling you that at this point of your program, SalesTaxPct was not declared yet, and looking at our list of variables / functions that the program knows about, we see that, indeed, SalesTaxPct is not on the list. Where do we expect the value of SalesTaxPct to come from?
It looks like that comes from the function getValues, and we are getting it from user input. However, any time that you have { ... }, the stuff inside the braces cannot be accessed outside. Therefore, SalesTaxPct is only "in scope" inside the function getValues. If you want it to be accessible outside of that function (which you do), you need to change things around a bit.
int main()
{
double base;
double opt;
double SalesTaxPct;
getValues(base, opt, SalesTaxPct);
getSalesTax(SalesTaxPct);
PrintFinal(base, opt, SalesTaxPct);
}
Now all of our variables still exist when we need them in main. However, there is still a problem here. We want the changes we pass into getValues to change the variables in main. This means we cannot pass "by value" because that will first make a copy, and then change those copies (not what we want). Instead, we need to say that the changes we make need to be returned from the function some how:
void getValues(double & base, double & opt, double & SalesTaxPct);
That little & there means that rather than making a copy and changing that copy, we are telling the function to operate on the variable we pass in directly. This is referred to as "pass by reference".
There are some similar problems in other parts of your code, but perhaps now you can figure out how to fix them.