I am attempting to write the following:
1) Write the class definition for a class named Employee with name and salary as employee objects. The class contains two member functions: the constructor and a function that allows a program to assign values to the data members.
2) Add two member functions to the Employee class. One member function should allow any program using an employee object to view the contents of the salary data member. The other member function should allow the program to view the contents of the employee name data member.
3) Add another member function to the Employeeclass. The member function should calculate an employee objects new salary, based on a raise percentage provided by the program using the object. Before calculating the raise, the member function should verify that the raise percentage is greater than or equal to zero. If the raise percentage is less than zero, the member function should display an error message.
4) Write a main function that will create an array of employee objects, assign
values to the objects, display the names and current salaries for all objects,
ask user for the raise percentage and then calculate and display new salaries
for all objects.
I have attempted this with the following code:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class EMPLOYEE
{
public:
EMPLOYEE();//
EMPLOYEE(string name, int salary);//
public:
string name;//name to be input
int salary;//salary to be input
public:
int enter_values();
int output_values();
int NEW_SALARY( int percentage_raise);
};
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
}
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name= NAME;
salary= SALARY;
}
//name and salary to be input...
int EMPLOYEE::enter_values()
{ cout<<"Enter name and salary: ";
cin>> name;
cin>>salary;
}
//output
int EMPLOYEE::output_values()
{ cout<<"Name: "<<name<<endl;
cout<<"Salary: "<<salary<<endl;
}
//
int EMPLOYEE::NEW_SALARY(int percentage_raise)
{
EMPLOYEE updated_salary;
if ( percentage_raise >= 0){salary= salary *(percentage_raise/100);
}
else if(percentage_raise< 0)
{ cout<<"Error Message"<<endl;
}
return percentage_raise;
}
int main()
{
EMPLOYEE employees[100];
EMPLOYEE.NEW_SALARY();
int percent= 0;
int i;
for(i =0 ;i<100 ; i++)
{ employees[i]=EMPLOYEE();
employees[i].enter_values();
employees[i].name;
employees[i].salary;
employees[i].output_values();
cout<<"How much should the salary be raised by?"<<endl;
cin>>percent;
cout<<EMPLOYEE.name<<"'s new salary is "<<percentage_raise<<endl;
}
}
However, I cannot access the parts I need to store the information into the array in the main function, nor can I apply the percentage raise when the program prompts the user.
I'm pretty sure I have syntax errors which I am unaware of. I'm not asking for someone to do everything for me, but I would appreciate a steer in the right direction. I don't quite understand classes and how to call them into different parts of a program. Thank you for your time.
You have almost everything in good order.
Things to fix:
The line
if ( percentage_raise >= 0){salary= salary *(percentage_raise/100);
will set salary to zero unless percentage_raise is greater than 100. That's because the expression (percentage_raise/100) will be an integer division and will evaluate to zero, unless pecentage_raise is greater than 100.
You can fix it with:
if ( percentage_raise >= 0)
{
int raise = (salary*percentage_raise)/100;
salary += raise;
}
The line
EMPLOYEE.NEW_SALARY();
is going to produce a compiler error since there is no object named EMPLOYEE.
You can safely remove that line. It's not serving any purpose.
You are missing a call to set the percentage raise after you read the input. You need the line
employees[i].NEW_SALARY(percent);
immediately after you read percent.
The following line is incorrect.
cout<<EMPLOYEE.name<<"'s new salary is "<<percentage_raise<<endl;
since there is no object named EMPLOYEE. You can replace it with:
cout<<employees[i].name<<"'s new salary is "<<employees[i].salary<<endl;
class Employee
{
public:
Employee();
int salary;
};
Employee::Employee() { salary = 10; }
int main()
{
Employee joe;
std::cout << "Joe Salary: " << joe.salary << std::endl;
joe.salary = 15;
std::cout << "Joe New Salary: " << joe.salary << std::endl;
}
Usually, you will want your data members to be private and use an accessor method to provide the values of the data members which, again, should be private.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I created a class with students and groups. The group consists of the group name and the number of students. The student class consists of:
student name, price, and logical operation scholarship.
My main goal is to find the average of the grades received by students in their group. However, if a student's scholarship is - > false, then we don't count them. This is the main problem. I created both classes, combined them using a vector, wrote a program so that it would display the average scores of the groups, but when I turn on the program, the console only displays the name of the first group.
I want to clarify that this task is for a two-dimensional array. I just changed it to vectors to learn about the vectors (I don't know vectors well, but I will learn more about vectors in the future).
Here's my code:
#include <iostream>
#include <vector>
using namespace std;
class Student {
public:
string name;
double grade;
bool Grant;
Student() {
string is_Grant;
cin >> name >> grade >> is_Grant;
if (is_Grant == "true") {
Grant = true;
} else
Grant = false;
}
string GetName() {
return name;
}
double Get_Grade() {
return grade /** (Grant)*/;
}
};
class Group {
public:
string G_Name;
int count;
vector<Student> stud;
Group() {
cin >> G_Name >> count;
vector<Student> stud(count);
}
double GetAverage()
{
cout << "\n";
double avg = 0;
for (int i = 0; i < count; i++)
{
avg += stud[i].Get_Grade();
}
return avg / stud.size();
}
};
int main() {
int size;
cin >> size;
vector<Group> grp(size);
for (int i = 0; i < size; i++)
{
cout << grp[i].G_Name << ": Average is " << grp[i].GetAverage() << endl;
}
}
I want to know where I made a mistake. Maybe I forgot to add something?
First, I was using Void GetAvg() instead of a string. At that time, when I only typed in the number of inputs, the program stopped there.
I also tried creating a bool value as a separate function, but it wouldn't output either.
Most importantly, I want to know why the program doesn't find the average value.
So your code is super weird and I'm not sure it can ever work, but there is one obvious error
Group() {
cin >> G_Name >> count;
vector<Student> stud(count);
}
that should be
Group() {
cin >> G_Name >> count;
vector<Student> s(count);
stud = s;
}
Your version creates a local variable called stud which is a vector with the given size, but that has nothing to do with the stud that is a member variable in the Group class. My version uses a different name and then assigns that variable to stud.
This is still weird code, the code I originally wrote in the answer was the more natural
Group() {
cin >> G_Name >> count;
vector<Student> s(count);
stud.resize(count);
}
but this code doesn't work because your strange constructors. This version of the code only creates one Student which is then copied to fill in the vector. So you would end up with count identical students. More on this in the last paragraph.
The reason for your error is that when you call GetAverage you have some value for count but because of the bug the size of stud is still zero, so you are accessing that vector out of bounds and that (probably) is what is crashing your code.
And that brings up another issue with your code. One of the reasons vectors are superior to arrays is that vectors know their own size, and so variables like count are redundant, just query the vector for it's size. Rewriting your code to take advantage of that gives you something like this
class Group {
public:
string G_Name;
vector<Student> stud;
// no count in group
and this
Group() {
int count; // count is now a local variable
cin >> G_Name >> count;
vector<Student> s(count);
stud = s;
}
and this
double GetAverage()
{
cout << "\n";
double avg = 0;
for (int i = 0; i < stud.size(); i++) // get the count from the vector
{
avg += stud[i].Get_Grade();
}
return avg / stud.size();
}
But the elephant in the room is the way you do data input in your constructors. Don't do that. It means that every time you declare a variable the program is going to pause and ask the user for input. It also means that every student you do want to create has to be created with the default constructor, which is why my resize code doesn't work. Think about how restricting that is going to be going forward.
In my code, I want to add one student info into my class pointer array and the array size will increase each time a new student is added. Here is my code:
My header file:
class Student{
public:
int studentID;
char studentName[20];
int currentEnrollment;
Student();
void AddStudent(Student *tempStudent[], int countStudent, int sizeOfArray);}
My Class definition file:
void Student::AddStudent(Student *tempStudent[], int countStudent, int sizeOfArray)
{
for (int i = countStudent; i < sizeOfArray; i++)
{
cout << "Please enter student id (4 digits only): ";
cin >> tempStudent[i]->studentID;
cout << "Please enter student name: ";
cin >> tempStudent[i]->studentName;
}
}
My Main.cpp file
int *totalStudent = new int;
*totalStudent = 1;
int i, j, countStudent = 0;
int sizeOfArray = *totalStudent;
Student *newStudent[*totalStudent];
//Each time a new student is added, I will allocate a new memory for the array element, then add student Info using function.
for (i = countStudent; i < *totalStudent; i++)
{
newStudent[i] = new Student;
newStudent[i]->AddStudent(newStudent, countStudent, sizeOfArray);
countStudent++;
*totalStudent++;
}
When I run my code, I get an undefined reference error, so I do not know If I am able to increase my array or not. I intend to use C++ syntax so I use new and delete. Thank you for your help.
P.S: Here is my new code and it runs great, the only missing is the studentID for the first element in array.
In my main class:
int numStudent = 0;
int i, j, countStudent = 1;
Student *newStudent = new Student[countStudent];
AddStudent(newStudent, countStudent, numStudent);
My Student.h
class Student{
public:
int studentID;
char studentName[20];
int currentEnrollment;
};
Student AddStudent(Student *newStudent, int &countStudent, int &numStudent);
and My Student.cpp
Student AddStudent(Student *newStudent, int &countStudent, int &numStudent)
{
Student tempStudent;
cout << "Please enter student id (4 digits only): ";
cin >> tempStudent.studentID;
cout << "Please enter student name: ";
cin >> tempStudent.studentName;
newStudent[numStudent] = tempStudent;
numStudent++;
if (numStudent == countStudent)
{
Student *newStudentSize = new Student[countStudent + 1];
for (int i = 0; i < numStudent; i++)
{
newStudentSize[i] = newStudent[i];
}
delete []newStudent;
return *newStudentSize;
countStudent += 1;
}
}
Running this code will give me the following result:
StudentID: 11
StudentName: Dat
StudentID: 23
StudentName: Michael
Printing:
StudentID: 0
StudentName: Dat
StudentID: 23
StudentName: Michael
While it doesn't make sense to increase the array for each new student (it's inefficient) here's one way you can do it (I didn't even try to make your code compile because it has a number of issues and is unnecessarily complicated). Note that tempStudent (in the code snippet below) doesn't even have to be created using new. This solution stores Student objects in the students array (although it's easy to modify it to store Student object pointers instead). That said, usually, you'll just want to create an array of large enough size to accomodate all students (just set studentCount to some appropriate number and not 1 like in the example below).
class Student{
public:
int studentID;
char studentName[20];
int currentEnrollment;
Student(){};
};
int main(){
int studentCount=1;
Student * students = new Student[studentCount];
int numStudents=0;
bool done=false;
char finished='N';
while (!done){
//Student *tempStudent = new Student();
//create a Student on the stack
Student tempStudent;
cout << "Please enter student id (4 digits only): ";
//No input checking is done here
cin >> tempStudent.studentID;
No input checking is done here
cout << "Please enter student name: ";
cin >> tempStudent.studentName;
students[numStudents] = tempStudent;
numStudents++;
cout << "Stop entering students: Y or N";
cin >> finished;
done = finished=='Y' or finished=='y' ? true : false;
if(numStudents==studentCount){
students = ReallocateStudents(students, studentCount, studentCount*2);
studentCount *= 2;
}
}//end while
//print the students info
for(int i=0;i<numStudents;i++){
Student st = students[i];
cout << st.studentID << " " << st.studentName << std::endl;
}
//deallocate the students array or if you place this in the main like you did, the program will exit immediately so there's no need to deallocate
return 0;
}
Student * ReallocateStudents(Student* st, int oldSize, int newSize){
Student * newStudents = new Student[newSize];
//copy the existing values from the old array to the new one
for(int i=0;i<oldSize;i++){
newStudents[i] = st[i];
}
delete [] st; //delete the old array
return newStudents;
}
UPDATE:
Since you don't want to do everthing in the main(), just create a free AddStudents function and do everything there. Alternatively, you can create a
static function inside the Student class. It makes no sense to create AddStudent as a member of Student because that would require you to use an instance of Student to add a new instance, which makes for poor design (not to mention technical issues etc).
int main(){
// some code here
Students * allStudents = AddStudents();
//print students
}//end main
Students * AddStudents(){
int studentCount=1;
Student * students = new Student[studentCount];
int numStudents=0;
bool done=false;
char finished='N';
while (!done){
//create a Student on the stack
Student tempStudent;
cout << "Please enter student id (4 digits only): ";
//No input checking is done here
cin >> tempStudent.studentID;
No input checking is done here
cout << "Please enter student name: ";
cin >> tempStudent.studentName;
students[numStudents] = tempStudent;
numStudents++;
cout << "Stop entering students: Y or N";
cin >> finished;
done = finished=='Y' or finished=='y' ? true : false;
if(numStudents==studentCount){
students = ReallocateStudents(students, studentCount,
studentCount*2);
studentCount *= 2;
}
}//end while
return students;
}
This is simple and easy to both understand and maintain so I suggest using this approach.
addStudent does not do anything with the Student object it belongs to. So there is no need to put it in the 'Student' class. (Or you could rather rewrite it so it does something with the student object it belongs to). And it currently does not "add" anything, so the name is confusing.
What is technically wrong with it depends on what you want it to do. Currently it initializes student objects expected to already exist and pointed to by an array, from a specific array index, to the end of the array. That could well be a useful function, if that is what you want it to do. But you then must call it correctly with an array of pointers that point to valid Student objects, which you currently do not.
Currently in main you have a loop that initializes pointers in an array. And each time you initialize a pointer, you call AddStudent(..). The problem is that 'AddStudent()' tries to initialize ALL the student pointed to by your array.
This has two major problems (In addition to all the other problems with your loop).
Each time you create a new student, all your existing students will be
initialized again with new input from std::cin. (So for n students, you will
try to do n*n initializations)
While the loop in main is running, not all pointers in your array points
to existing Student objects. This may result in important data being
overwritten, a program crash or something totally different and unexpected.
You should sit back and reevaluate how you want to do things. Trying to fix single bugs in your existing code, one after another, will just create more bugs.
Just a hint to get you started:
class Student
{
public:
int studentID;
char studentName[20];
int currentEnrollment;
Student();
void init_from_cin();
};
And in your class definition file:
void Student::init_from_cin()
{
cout << "Please enter student id (4 digits only): ";
cin >> studentID;
cout << "Please enter student name: ";
cin >> studentName;
}
If you create a new Student like this:
Student *new_student = new Student;
new_student->init_from_cin();
Then after calling init_from_cin(), the Student object pointed to by new_student should be initialized.
How to create and initialize multiple Student objects in a loop, is left as exercise for the reader. But when you do it, you should understand what your lower and upper bounds of your loop are supposed to be. And you should also understand why moving the upper bound further away while your loop is running is a bad idea.
And never forget that sane programming languages start array indexing with 0.
So... I tried to make an in-game shop system that reads player's account balance out of .txt file, but I've encountered this realy weird problem
So. This int works just fine. It reads data out of file, converts string to a numeric value, and prints it out.
int main() {
int money;
string cash;
ifstream playerdata;
playerdata.open("player.txt");
if (playerdata.is_open()) {
getline(playerdata,cash);
money = atoi(cash.c_str());
} else cout<<"error";
return money;
}
While this one doesn't. It always prints out that cash is equal to 0.
class Player {
int money ;
string cash;
public:
GetMoney();
int PrintMoney() {return atoi(cash.c_str());};
};
Player::GetMoney(){
int money;
string cash;
ifstream playerdata;
playerdata.open("player.txt");
if (playerdata.is_open()) {
getline(playerdata,cash);
money = atoi(cash.c_str());
playerdata.close();
} else cout<<"error";
}
int main() {
Player a;
cout<<"Your Money: "<<a.PrintMoney()<<"$";
};
Your logic in main is as follows:
Create a of type Player.
Call PrintMoney() function on a.
Your implementation of the PrintMoney function does not call the GetMoney function. In this case, cash is an empty string. Calling c_str on this empty string will result in an empty value being passed to atoi, which will return a 0.
According to the domain this appears correct. The Player doesn't yet have any money. Perhaps after declaring a you need to call a.GetMoney(), however there are other problems with your code that mean this won't quite work.
The money and cash variables in the GetMoney function will override the variables in the Player class. You should remove these.
I initialized objects in my code using a house number (int) and the person's name (string). This part of my code works and it displays the house number and person correctly.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
//AddressBook class definition
class AddressBook
{
public:
//Declare a constructor that has one parameter for each data member
AddressBook(int, string);
//Declare a set method for house number
void setHouseNum(int);
//Declare a get method for house number
int getHouseNum();
//Declare a set method for name
void setName(string);
//Declare a get method for name
string getName();
void displayAddressBook();
private:
//Declare a int data member for house number
int houseNum;
//Declare a string data member for name
string name;
};
// constructor
AddressBook::AddressBook(int num, string personName)
{
setHouseNum(num);
setName(personName);
}
void AddressBook::setHouseNum(int num)
{
houseNum = num;
}
int AddressBook::getHouseNum()
{
return houseNum;
}
void AddressBook::setName(string personName)
{
name = personName;
}
string AddressBook::getName()
{
return name;
}
void AddressBook::displayAddressBook()
{
cout << getHouseNum() << " " << getName() << endl;
}
int main()
{
AddressBook addressBook(3, "Jim");
addressBook.displayAddressBook();
AddressBook addressBook2(5, "Bob");
addressBook2.displayAddressBook();
AddressBook addressBook3(2, "Jeb");
addressBook3.displayAddressBook();
string command;
cout << "Available Commands Are:" << endl;
cout << "Add, Remove, Sort, Print" << endl;
return 0;
}
Output:
3 Jim
5 Bob
2 Jeb
Available Commands Are:
Add, Remove, Sort, Print
The next part is what I'm having trouble with. I'm supposed to read the user input to see what they want to do and perform the operations listed above. So, if they say Add, and then enter "2 Jeb", the code has to say 2 already exists. If it doesn't exist, it has to add it as an object and print the entire list back out.
I know that you can use getline(cin,name) to get the name from the user but I do not know how to implement that in my code to do what I want it to. Once I get the user input string, how do I create an object with it? Also, how do you read an integer the user inputs into an object because I read that getline works for strings and not integers.
Once I read the integer and string input from the user, how do I check if the house number already exists in my objects? If I can get some help with just these two things I can figure the rest out.
Thank you.
I have been working in this program for a while but I am just not able to do it. It is for my programming class.
Here is the part of the program that I am (will have to) working on...
void AutoInventory::addCar()
{
if (count == list.length())
list.changeSize(2* list.length());
count++;
cout <<"Enter the VIN: ";
cin >> VINnumber; // I get the same error when I try using the one in the public.
list[count] = c; // Error: identifier c is undefined
//list [next] = count;
count++;
cout << "Enter the make ";
cin >> make; // Error: identifier make is undefined
list[count] = c;
//list [next] = count;
count++;
cout<< "Enter the model ";
cin >> model;
list[count] = c;
//list [next] = count;
count++;
cout <<"Enter Year ";
cin >> year;
list[count] = c;
//list [next] = count;
count++;
cout << "Car has been successfully added";
}
What I basically have to do is (in this function), prompt the user to enter the make, model, year of a car, and save the data on the "next element of the array" (which I'm not really sure what it means but I am not there yet, I still need to figure out the first part ) and print out the confirmation(which obviously doesn't have any errors ha ha!)
So, My question is, How do we use the variables that have been declared in another file and use it in this. To be specific, The Make, model, year is declared in a private section of another file (which I have #includeded in this file) however it gives me a compile error saying the identifiers make, model and yeear are undefined.
the file that has these variables is ....
#ifndef AUTOMOBILE_H
#define AUTOMOBILE_H
#include <string>
using namespace std;
class Automobile
{
public:
Automobile();
void setVIN(string v);
void setMake(string ma);
void setModel(string mo);
void setYear(int y);
string getVIN();
string getMake();
string getModel();
int getYear();
private:
string VINnumber;
string make;
string model;
int year;
};
#endif
If anyone could just let me know how to use the variable in the other file.
I am sorry If this question is against the rules of the website but I am desperate.
To be specific, The Make, model, year is declared in a private section of another file ...
If the member variables of class are private, then they can be accessed only by its member functions ( Even if there is a inheritance relationship between the Automobile and AutoInventory). In your example, only Automobile class member functions can access them directly.