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);
}
Related
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.
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();
}
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);
}
I have written a code for Knapsack problem.The code is working perfectly when i hardcode the inputs but now i want to take the inputs from the user in the array of structures but it is showing error.How can i achieve this?
original code:
#include<iostream>
#include<algorithm>
using namespace std;
struct Item{
int value;
int weight;
Item(int value,int weight):value(value),weight(weight){
}
};
bool cmp(struct Item a,struct Item b){
float r1=(float)a.value/a.weight;
float r2=(float)b.value/b.weight;
//cout<<r1<<" "<<r2<<endl;
return r1>r2;
}
void knapsack(int m,int n,struct Item arr[]){
sort(arr,arr+n,cmp);
/* for(int i=0;i<n;i++){ //new sorted array
cout<<arr[i].value<<" "<<arr[i].weight<<" ";
}*/
cout<<endl;
float result[n];
for(int i=0;i<n;i++){
result[i]=0.0;
}
int rem=m;
int j=0;
for(j=0;j<n;j++){
if(arr[j].weight>rem){
break;
}
else{
result[j]=1;
rem=rem-arr[j].weight;
}
}
if(j<n){
result[j]=(float)rem/arr[j].weight;
}
for(int k=0;k<n;k++){
cout<<result[k]<<" ";
}
}
int main(){
struct Item arr[]={{25,18},{24,15},{15,10}};
knapsack(20,3,arr);
return 0;
}
Now i want to take user input in the array of structures but it shows an error "no matching function to call to"
#include<iostream>
#include<algorithm>
using namespace std;
struct Item{
int value;
int weight;
Item(int value,int weight):value(value),weight(weight){
}
};
bool cmp(struct Item a,struct Item b){
float r1=(float)a.value/a.weight;
float r2=(float)b.value/b.weight;
//cout<<r1<<" "<<r2<<endl;
return r1>r2;
}
void knapsack(int m,int n,struct Item arr[]){
sort(arr,arr+n,cmp);
/* for(int i=0;i<n;i++){ //new sorted array
cout<<arr[i].value<<" "<<arr[i].weight<<" ";
}*/
cout<<endl;
float result[n];
for(int i=0;i<n;i++){
result[i]=0.0;
}
int rem=m;
int j=0;
for(j=0;j<n;j++){
if(arr[j].weight>rem){
break;
}
else{
result[j]=1;
rem=rem-arr[j].weight;
}
}
if(j<n){
result[j]=(float)rem/arr[j].weight;
}
for(int k=0;k<n;k++){
cout<<result[k]<<" ";
}
}
int main(){
struct Item arr[10];
int n,m;
cin>>m>>n;
for(int i=0;i<n;i++){
cin>>arr[i].value>>arr[i].weight;
}
knapsack(m,n,arr);
return 0;
}
Check below code:
struct Item{
int value;
int weight;
Item(int value,int weight):value(value),weight(weight){
}
};
There is no default constructor. So the below line fails:
struct Item arr[10];
But the following line works:
struct Item arr[]={{25,18},{24,15},{15,10}};
Solution[1]: Provide a default constructor or remove the explicit constructor.
[1] There may be more problems in the code, but I looked into the one you pointed in your question.
You have provided parameterized constructor Item(int value,int weight), so compiler won't generate default constructor by itself.
You have to define the default constructor explicitly to make the below statement work since it needs default constructor.
struct Item arr[10];
But the below line of code uses the parameterized constructor you have provided.
struct Item arr[]={{25,18},{24,15},{15,10}};
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.