Is it possible to set the class functions in the two functions? - c++

I don't know how to call my class functions into printData(Testscore&) and readData(TestScore).
Also, could someone tell me why my Average() isn't being called to the main? I just learned about using static member variables and static member functions and was wondering if I am using them incorrectly.
The readData function:
Does not use copy constructor.
Reads all instance variables like the student's names and all their
grades.
Uses functions to store the variables, name, element of each grade of array pointed to private pquiz, and static member
grades of how many grades to read.
The printData function:
Writes the name and average grade of the quizzes.
Uses copy constructor.
This is my program so far:
#include <iostream>
#include <string>
using namespace std;
class TestScore {
private:
static int grades;
string name;
double *pquiz;
double average;
public:
TestScore();
~TestScore();
void setName(string);
static void setGrades(int);
void setPquiz(double *);
void setAverage(double);
string getName();
static int getGrades();
double getPquiz();
void readData(TestScore &);
void printData(TestScore);
double Average(double *, int);
static void Grade(int);
};
TestScore::TestScore() {
name="";
pquiz=new double[grades];
average=0;
}
void TestScore::setName(string name1) {
if(name1!="1") {
name=name1;
}
}
void TestScore::setPquiz(double *pquiz1) {
if(pquiz>=0) {
pquiz=pquiz1;
}
}
void TestScore::setGrades(int grades1) {
if(grades1>=0) {
grades=grades1;
}
}
void TestScore::setAverage(double average1) {
if(average1>=0) {
average=average1;
}
}
string TestScore::getName() {
return name;
}
int TestScore::getGrades() {
return grades;
}
double TestScore::getPquiz() {
return *pquiz;
}
double Average(double *pquiz, int grade) {
int count;
double total=0;
double average=0;
for(count=0; count<grade; count++) {
total+=pquiz[count];
}
average=total/grade;
return average;
}
void readData(TestScore&) {
}
void printData(TestScore) {
}
TestScore::~TestScore() {
delete [] pquiz;
pquiz=0;
}
int TestScore::grades=0;
void TestScore::Grade(int a) {
grades+=a;
}
int main() {
const int grades = 3;
const int students = 4;
TestScore exam;
string student;
int grade;
double *pquiz;
double average;
for(int i=0; i<students; i++) {
cout<<"Student "<<(i+1)<<": ";
cin>>student;
exam.setName(student);
cout<<endl;
for(int count=0; count<grades; count++) {
cout<<"Quiz "<<(count+1)<<": ";
cin>>pquiz[count];
exam.setPquiz(pquiz);
exam.getPquiz();
while(pquiz[count]<0) {
cout<<"Error, invalid test score, please try again."<<endl;
cout<<"Quiz "<<(count+1)<<": ";
cin>>pquiz[count];
}
}
exam.setAverage(average);
cout<<exam.getName()<<" average is "<<Average(pquiz, grade)<<endl<<endl;
}
readData(exam);
printData(exam);
return 0;
}

Don't use static anywhere, at least not for now. You have too many variables of the same name, scattered all over the place. Try to clean them up.
TestScore::TestScore()
{
name = "";
//pquiz = new double[grades];//#grades is undefined
pquiz = NULL;
average = 0;
}
grades is not defined yet, it could be zero, or it could be -817. You should just remove that line, or you can put something like pquiz = new double[10] that's if you are sure the number of quiz will not exceed 10.
TestScore::~TestScore()
{
if (pquiz) delete[] pquiz;
pquiz = NULL;
}
delete pquiz only if it is not NULL
int main() {
const int grades = 3;
const int students = 4;
TestScore exam;
string student;
int grade;
double *pquiz;
...
This is a different pquiz, it is a pointer which points to nothing, it doesn't really exist, you can't use it like that.

Related

Im trying to assign value to a array of char using strcpy(), but it gives a error that cannot convert char** to char*

I'm working on a assignment and I can't seem to figure out the reason of the error. The strcpy() function was working when I tried on the University's PC, now I'm trying to do it at home and its not working properly.
#include<iostream>
using namespace std;
#include<conio.h>
#include<string.h>
class Employee{
int E_Id;
char*E_Name[30];
int No_Hours;
int Rate_Hour;
public:
void SetData(int Id, char*Name[30], int Hours, int Rate)
{
E_Id = Id;
strcpy(E_Name,Name); //Error Here
No_Hours = Hours;
Rate_Hour = Rate;
}
void DispData()
{
cout<<"Employee ID: "<<E_Id<<endl;
cout<<"Employee Name: "<<E_Name<<endl;
cout<<"Number of Hours: "<<No_Hours<<endl;
cout<<"Rate per Hour: "<<Rate_Hour<<endl;
}
void InputData()
{
cout<<"Give Employee ID: ";
cin>>E_Id;
cout<<"Give Employee Name: ";
cin>>E_Name;
cout<<"Give Number of Hours: ";
cin>>No_Hours;
cout<<"Give Rate per Hour: ";
cin>>Rate_Hour;
}
int GetEId()
{
return E_Id;
}
char*GetEName()
{
return E_Name;
}
int GetNoHours()
{
return No_Hours;
}
int GetRateHour()
{
return Rate_Hour;
}
Employee()
{
PId = 0;
strcpy(E_Name, "")
No_Hours = 0;
Rate_Hour = 0;
}
Employee(int Id, char*Name, int Hours, int Rate)
{
E_Id = Id;
strcpy(E_Name, Name); //Error Here
No_Hours = Hours;
Rate_Hour = Rate;
}
~Employee()
{
cout<<"Obeject Destroyed"<<endl;
}
};
int main()
{
Employee*e;
e = new Employee[10];
int i;
cout<<"Give Data"<<endl;
for(i=0;i<10;i++)
{
(e+i)->InputData();
}
int high = (e+0)->GetNoHours()*(e+0)->GetRateHours();
int loc = 0;
for(i=0;i<10;i++)
{
if((e+i)->GetNoHours()*(e+i)->GetRateHours()>high)
{
high = (e+i)->GetNoHours()*(e+i)->GetRateHours();
loc = i;
}
}
cout<<"Employee with Highest Salary"<<endl;
(e+loc)->DispData();
delete[]e;
getch();
return 0;
}
In this program have to use pointers to make an array of 10 employees and tell which employee earns the most salary.
This is wrong
char*E_Name[30]; // array of char pointers
it should be
char E_Name[30]; // array of chars
An array of chars can hold a string. An array of char pointers is something else.
This is wrong
void SetData(int Id, char*Name[30], int Hours, int Rate)
it should be
void SetData(int Id, char*Name, int Hours, int Rate)
Since you cannot have an array as a parameter to a function you use a pointer instead. So if you want to pass an array of char to a function, the function should be declared with a pointer to char.
Basically you should be using either char arrays or char pointers, but not both combined.

Sort a list of objects by property in C++ using the standard list

I am currently trying to sort a list of objects in this case students, based on their grades, student number, name, etc.
listOfStudents.sort([](const Students& student1, const Students& student2)
{
if (student1.getStudentNumber() == student2.getStudentNumber())
return student1 < student2;
return student1.getStudentNumber() < student2.getStudentNumber();
});
This is the code I am currently using to sort the list based on their student number but it points an error to the student1 and student2 saying "The object has type qualifiers that are not compatible".
Here is the code for the Student Class:
class Students {
int studentNumber;
string studentName;
int grade1;
int grade2;
int grade3;
int grade4;
int grade5;
int total;
public:
void setStudent(int number, string name, int g1, int g2, int g3, int g4, int g5, int total) {
this->studentNumber = number;
this->studentName = name;
this->grade1 = g1;
this->grade2 = g2;
this->grade3 = g3;
this->grade4 = g4;
this->grade5 = g5;
this->total = total;
}
int getStudentNumber() {
return this->studentNumber;
}
string getStudentName() {
return this->studentName;
}
int getGrade1() {
return this->grade1;
}
int getGrade2() {
return this->grade2;
}
int getGrade3() {
return this->grade3;
}
int getGrade4() {
return this->grade4;
}
int getGrade5() {
return this->grade5;
}
int getTotal() {
return this->total;
}
};
and this is the implementation part
list <Students> listOfStudents;
Students students;
The above codes are currently producing errors about the list type qualifiers etc.
Did I miss something? Im sure I did. Thank you in advance for relieving my idiocy.
int getStudentNumber() {
return this->studentNumber;
}
should be
int getStudentNumber() const {
return this->studentNumber;
}
and the same for all the other getters in your code.
Okay, so I've read some comments. and yes I forgot to make the <() operator. I knew I had missed something.
and also making the getters const is important, and apparently, I forget them as well.
Here is the updated code and it is now working. Thanks, everyone.
In the Student Class:
bool operator <(const Students& studentObj) const {
return this->getStudentNumber() < studentObj.getStudentNumber();
}

Adding Objects from a Class to another Class

INPUT STDIN -> <street> <city> <house_number> <number of objects of house> <object1> <price1> .......<object-n> <price-n> (until EOF)
I need to use the "add" method in the "House" Class.
objective: adding the specific n objects of each House in "House" class
This is what i did since now:
#include <iostream>
#include <utility>
#include<vector>
#include<string>
using namespace std;
class Object {
public:
string valuable;
float price;
public:
Object() : Object("",0) {}
Object(string v, float p) : valuable(std::move(v)), price(p) {}
string getValuable() {
return valuable;
}
float getPrice() {
return price;
}
};
class House{
public:
string street;
string city;
uint32_t number;
vector<Object>valuables;
public:
House(): House("","",0){}
House(string s,string c,uint32_t n): street(std::move(s)),city(std::move(c)),number(n){}
string getStreet() {
return street;
}
string getCity() {
return city;
}
uint32_t getNumber() {
return number;
}
uint32_t getValuablesSize() {
return valuables.size();
}
Object getValuable(uint32_t x){
return valuables[x];
}
void add(Object a){
valuables.emplace_back(a);
}
};
float getTotalPrice(House a) {
float sum = 0;
for (int i = 0; i < a.getValuablesSize(); i++) {
sum +=a.valuables[i].getPrice();
}
return sum;
}
int main() {
vector<Object>obj;
vector<House>house;
char object[30],street[30],city[30];
float price;
uint32_t house_number;
int n;
while(cin>>street>>city>>house_number>>n) {
house.emplace_back(string(street),string(city),house_number);
Object a;
for(int i=0;i<n;i++){
cin>>object>>price;
obj.emplace_back(object,price);
a.valuable=object;
a.price=price;
for(int k=0;k<house.size();k++)
house[k].add(a);
}
}
for(int i=0;i<obj.size();i++){
cout<<obj[i].getValuable()<<" "<<obj[i].getPrice()<<endl;
} // trying to print the object vector
for(int i=0;i<house.size();i++){ //trying to verify if i have the correct input
cout<<house[i].getStreet()<<" "<<house[i].getCity()<<" "<<house[i].getNumber()<<" ";
for(int j=0;j<house[i].getValuablesSize();j++) {
cout << house[i].valuables[j].valuable<< " "<<house[i].valuables[j].price<<" ";
}
cout<<endl;
}
return 0;
}
That's what i think:
-when i read <house_number> ,read the objects and prices and then the add method should be used in order to have the vector<Object>valuables usable.
It's necesarly to check if the input is stored corectly in the class "House", in order to continue summing the objects in every house
With the statements
for(int k=0;k<house.size();k++)
house[k].add(a);
you add the current "valuable" object to every house that has been created thus far.
I suggest you instead create the house object separately, then add the valuable objects to the current house, and after that add the house to your collection of houses.
Perhaps something like:
std::string street;
std::string city;
unsigned house_number;
unsigned n;
while(std::cin >> street >> city >> house_number >> n) {
House current_house(street, city, house_number);
std::string object;
float price;
for(int i = 0; i < n && std::cin >> object >> price; ++i) {
Object a(object, price)
current_house.add(a);
}
house.push_back(current_house);
}

How do you pass struct parameters in a method

I did not find anywhere the answer for my issue, I am pretty new to OOP so please give me mercy.
Okay so I have the following code:
class Group
{
public:
struct Student
{
char name[40],
int grades[5]};
}
Student s[10];
.....
private: double med(???)
{
.....
}
}
So where's ??? I want to have as parameters the grades of an individual student and return the average of them. I don't know how should I declare them, I tried in many ways but I get errors everytime.
Ty a lot
So you have a struct with parameters, like:
struct Student
{
std::string name;
std::array<int, 5> grades;
};
Since this is tagged C++, I chose to use a std::array<int, 5> rather than int[5].
In my opinion, Student should not be necessarily inside of Group, but I guess that's opinion based.
Now you have a Group which contains students:
struct Group
{
Group(std::vector<Student> students) :
_students{ std::move(students) }
{}
double med(/* ... */) const
{ /* ... */ }
std::vector<Student> _students; // C++ -> use std::vector
};
Say you want to pass the grades of a particular student as parameter of the function med, than you would simply do:
double Group::med(const std::array<int, 5>& grades) const
{ /* sum up grades, divide by 5, and return the result */ }
And you would call this function as follows:
Student paul{"Paul", {1,2,3,4,5}};
Group group({paul});
group.med(paul.grades);
As suggested in the comments, you might want to pass the name of a student instead of his/her grades:
double med(const std::string& name)
{
// find student
auto it = std::find_if(_students.begin(), _students.end(), [&name](const Student& student)
{
return student.name == name;
});
// if no student by that name
if (it == _students.end())
return -1.0;
// else
int sum{ 0 };
for (const auto& grade : it->grades)
{
sum += grade;
}
return static_cast<double>(sum)/(it->grades.size());
}
Here is a discussion about good C++ books.
Tyr this code Contains four avg() functions all are same but differ in how the functions are called.
#include<iostream>
#include<string.h>
using namespace std;
class Group
{
public:
struct Student
{
char name[40];
int grades[5];
}student;
double avg()
{
double sum=0;
for(int i=0;i<5;i++)
sum+=student.grades[i];
return (sum/5);
}
};
double avg(int *grade)
{
double sum=0;
for(int i=0;i<5;i++)
sum+=grade[i];
return (sum/5);
}
double avg(Group::Student stduent)
{
double sum=0;
for(int i=0;i<5;i++)
sum+=stduent.grades[i];
return (sum/5);
}
double avg(Group group)
{
double sum=0;
for(int i=0;i<5;i++)
sum+=group.student.grades[i];
return (sum/5);
}
int main()
{
Group group1;
strcpy(group1.student.name,"MyName");
for(int i=0;i<5;i++)
group1.student.grades[i]=5;
cout<<"Name:"<<group1.student.name<<endl;
cout<<"Avg:"<<avg(group1.student.grades)<<" "<<avg(group1.student)<<" "<<avg(group1)<<" "<<group1.avg();
return 0;
}
Output:
Name:MyName
Avg:5 5 5 5
Process returned 0 (0x0) execution time : 0.379 s
Press any key to continue.
You may leave the structure unnamed like
struct
{
char name[40];
int grades[5];
}student;
If you delete the function and function call from the code
double avg(Group::Student stduent)
{
double sum=0;
for(int i=0;i<5;i++)
sum+=stduent.grades[i];
return (sum/5);
}

Array of pointers to an object in C++

I am trying to write a super basic program which creates an array of objects under class Receipt. The class includes an int price, string good (name), and a simple function that adds an item to the list. I am stuck because every time I compile it seg faults before it even gets to the add function, meaning something is wrong with my default constructor.
I am still really new to C++ and pointers are probably my biggest struggle. I have looked online and at my lecture notes trying to figure out what I am doing wrong. I feel like it's something small but I cannot figure it out.
Here is my program:
#include <iostream>
#include <string>
using namespace std;
class Receipt {
private:
int price;
string good;
Receipt* goods[500]; //partially filled array
public:
Receipt();
void add(string name, int cost);
string getName();
int getPrice();
void setName(string name_in);
void setPrice(int price_in);
void displayList();
};
Receipt::Receipt()
{
for (int i=0; i < 500; i++)
{
goods[i]->setName("Empty");
goods[i]->setPrice(-1);
}
}
void Receipt::add(string name, int cost)
{
int place=0;
for (int i=0; i <500; i++)
{
if (goods[i]->getName()=="Empty" && goods[i]->getPrice()==-1)
{
place = i;
break;
}
}
goods[place]->setName(name);
goods[place]->setPrice(cost);
}
int Receipt::getPrice()
{
return price;
}
string Receipt::getName()
{
return good;
}
void Receipt::setName(string name_in)
{
good = name_in;
}
void Receipt::setPrice(int price_in)
{
price = price_in;
}
void Receipt::displayList()
{
//just displaying first item in list for debugging purposes
cout << goods[0]->getName() << endl << goods[0]->getPrice();
}
int main()
{
Receipt mine; //seg faults here
mine.add("banana", 50);
mine.displayList();
return 0;
}
your design is wrong, you have array of Receipt inside Receipt so when you initialize the object, it create 500 where each of them create another 500 endlessly. I think you want to create something like this instead
#include <iostream>
#include <string>
using namespace std;
class Receipt {
private:
int price;
string good;
public:
void setName(string name_in);
void setPrice(int price_in);
string getName();
int getPrice();
};
class Receipts {
private:
Receipt* goods[500]; //partially filled array
public:
Receipts();
void add(string name, int cost);
void displayList();
};
Receipts::Receipts()
{
for (int i = 0; i < 500; i++)
{
goods[i] = new Receipt();
goods[i]->setName("Empty");
goods[i]->setPrice(-1);
}
}
void Receipts::add(string name, int cost)
{
int place = 0;
for (int i = 0; i <500; i++)
{
if (goods[i]->getName() == "Empty" && goods[i]->getPrice() == -1)
{
place = i;
break;
}
}
goods[place]->setName(name);
goods[place]->setPrice(cost);
}
int Receipt::getPrice()
{
return price;
}
string Receipt::getName()
{
return good;
}
void Receipt::setName(string name_in)
{
good = name_in;
}
void Receipt::setPrice(int price_in)
{
price = price_in;
}
void Receipts::displayList()
{
//just displaying first item in list for debugging purposes
cout << goods[0]->getName() << endl << goods[0]->getPrice();
}
int main()
{
Receipts mine; //seg faults here
mine.add("banana", 50);
mine.displayList();
return 0;
}