Throwing this out there first I'm a still learning how to program in school. I'm having an issue reading in to a dynamically created array with a pointer to one of my classes. The function readClassArray() isn't getting the variable back from student.getCreditNumber. The program complies fine in Visual Studio but when I get the the readClassArray it just skips over the function because s.getCreditNumber returns 0.
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
using namespace std;
class Courses{
private:
int courseNumber;
double hours;
string courseName;
char grade;
public:
void setCourseNumber(int n){courseNumber = n; }
void setCreditHours(double c) { hours = c; }
void setCourseName(string n) { courseName = n; }
void setGrade(char g) { grade = g; }
int getCourseNumber() { return courseNumber; }
double getCreditHours() { return hours; }
string getCourseName() { return courseName; }
char getGrade() { return grade; }
};
class Student : public Courses{
private:
string firstName;
string lastName;
string studentNumber;
int creditNumber;
double gpa;
public:
Courses * courses;
Student() {
firstName = " ";
lastName = " ";
studentNumber = " ";
creditNumber = 0;
gpa = 0.0;
courses = NULL;
}
~Student() {
delete[] courses;
};
void setFirstName(string n) { firstName = n; }
void setLastName(string l) { lastName = l; }
void setStudentNumber(string a) { studentNumber = a; }
void setCreditNumber(int num) { creditNumber = num; }
string getFirstName() { return firstName; }
string getLastName() { return lastName; }
string getStudentNumber() { return studentNumber; }
int getCreditNumber() { return creditNumber; }
};
#endif
Student.cpp
#include "Student.h"
#include <iostream>
#include <string>
using namespace std;
void readStudent();
void readCourseArray();
void computeGPA();
void printSummary();
void readStudent() {
Student a;
string number;
string firstName;
string lastName;
int courses;
cout << "Enter student number: ";
cin >> number;
a.setStudentNumber(number);
cout << "Enter student first name: ";
cin >> firstName;
a.setFirstName(firstName);
cout << "Enter student last name: ";
cin >> lastName;
a.setLastName(lastName);
cout << "Enter student number of courses: ";
cin >> courses;
a.setCreditNumber(courses);
cout << "\n"; }
void readCourseArray(){
Student s;
s.courses = new Courses[s.getCreditNumber()];
int num;
double cHours;
string cName;
char grade;
cout << "test" << endl;
for (int i = 0; i < s.getCreditNumber(); i++){
cout << "Enter class " << i + 1 << " number: ";
cin >> num;
s.courses[i].setCourseNumber(num);
cout << "Enter class " << i + 1 << " name: ";
cin >> cName;
s.courses[i].setCourseName(cName);
cout << "Enter class " << i + 1 << " hours: ";
cin >> cHours;
s.courses[i].setCreditHours(cHours);
cout << "Enter class " << i + 1 << " grade: ";
cin >> grade;
s.courses[i].setGrade(grade);
cout << "\n";
}
}
At the start of readCourseArray you've created s. When that happens the value of the creditNumber member is 0 as set by the default constructor. You need to do something to set it to a non-zero value. If you're expecting the value set in readStudent to carry over you need to plumb the two functions together. Either pass in a Student object as a reference to each function, or have readStudent return a Student object and pass that to readCourseArray.
Related
I'm trying to write a C++ code for a course I'm enrolled in, where I keep the information of the students enrolled in the course.
I should be able to add a student to the classrrom in the user interface written in main , by calling the function void addNewStudent(int ID, string name, string surname), where I create my object instances, Student, and Course inside the function.
I should also be able to search by given ID by calling the function void showStudent(int ID) in the main, where the function uses the getStudent(ID) method of the object of the classCourse
I did not write all the methods, but when I try to debug this code, I got the error " Exception has occured, unknown signal error."
My questions are:
What is the reason of this error? How can I fix it?
Suppose that the user interface in the main is necessary to use as well as the functions it calls. Do I have to create a class object again inside each function as I wrote?
Can a more effective implementation be made in accordance with the object oriented principles I have defined above?
#include <iostream>
using namespace std;
#define MAX 10
class Student {
private:
int ID;
string name;
string surname;
public:
Student()
{
ID = 0;
string name = "" ;
string surname = "";
}
void setID(int ID_set);
int getID();
void setName(string name_set);
string getName();
void setSurName(string surname_set);
string getSurName();
};
class Course {
private:
Student students[MAX];
int num =0 ; // The current number of students in the course, initially 0.
float weightQ;
float weightHW;
float weightF;
public:
Course()
{
students[num] = {};
weightQ = 0.3;
weightHW = 0.3;
weightF = 0.4;
}
int getNum(); // Returns how many students are in the course
void addNewStudent(Student new_student);
void updateWeights(float weightQ_update, float weightHW_update, float weightF_update);
void getStudent(int ID_given);
};
// Method declerations for the class Student
void Student :: setID(int ID_set){
ID = ID_set;
}
int Student :: getID(){
return ID;
}
void Student :: setName(string name_set){
name = name_set;
}
string Student :: getName(){
return name;
}
void Student :: setSurName(string surname_set){
surname = surname_set;
}
string Student :: getSurName(){
return surname;
}
// Method declerations for the class Course
int Course :: getNum(){
return num;
}
void Course :: addNewStudent(Student new_student){
students[num] = new_student ;
num = num + 1;
}
void Course :: updateWeights(float weightQ_update, float weightHW_update, float weightF_update){
weightQ = weightQ_update;
weightHW = weightHW_update;
weightF = weightF_update;
}
void Course :: getStudent(int ID_given){
for(int i = 0; i<MAX; i++){
if(ID_given == students[i].getID()){
cout << "Student Name & Surname : " << students[i].getName() << " " << students[i].getSurName()<<"\n";
}
}
}
void addNewStudent(int ID, string name, string surname){
Student student;
Course ECE101;
student.setID(ID);
student.setName(name);
student.setSurName(surname);
ECE101.addNewStudent(student);
}
void showStudent(int ID){
Course ECE101;
ECE101.getStudent(ID);
}
int main(){
Course ECE101;
cout << "Welcome to the ECE101 Classroom Interface"<<"\n";
cout << "Choose your option\n";
string option_1 = "1) Add a student ";
string option_2 = "2) Search a student by ID";
cout << "Enter your option: ";
int x;
int ID;
string name, surname;
cin >> x;
if (x == 1)
cout << "Enter the student ID ";
cin >> ID;
cout << endl;
cout << "Enter the student name ";
cin >> name;
cout << endl;
cout << "Enter the student surname " ;
cin >> surname;
addNewStudent(ID, name, surname);
return 0;
}
To make the menu more interactive you could add a do while statement that would accept 3 options:
register
show data
exit
int main(){
Course ECE101;
int x;
int ID;
string name, surname;
string option_1 = "1) Add a student\n";
string option_2 = "2) Search a student by ID\n";
cout << "Welcome to the ECE101 Classroom Interface\n";
cout << "Choose your option\n";
cout << option_1 << option_2;
cin >> x;
do {
if (x == 1) {
cout << "Enter the student ID ";
cin >> ID;
cout << endl;
cout << "Enter the student name ";
cin >> name;
cout << endl;
cout << "Enter the student surname " ;
cin >> surname;
addNewStudent(ID, name, surname, ECE101);
}
else {
cout << "Enter the student ID\n";
cin >> ID;
showStudent(ID, ECE101);
}
cout << "Choose your option\n";
cin >> x;
} while(x != 3);
return 0;
}
addnewStudent() and showStudent() methods now accepts an instance of Course as an argument to be able to add students.
void addNewStudent(int ID, string name, string surname, Course &course) {
Student student;
student.setID(ID);
student.setName(name);
student.setSurName(surname);
course.addNewStudent(student);
}
void showStudent(int ID, Course &course) {
course.getStudent(ID, course);
}
the function is modified from the same class as well.
void Course::getStudent(int ID_given, Course &course) {
for(int i = 0; i<MAX; i++){
if(ID_given == students[i].getID()){
cout << "Student Name & Surname : " << students[i].getName() << " " << students[i].getSurName()<<"\n";
}
}
}
Demo
Your addNewStudent function creates a new course everytime it is called. You could pass a reference to the course as a parameter into the function and call Course.addNewStudent(student). You'll want to make sure you specify it's a reference though when you define your function or you'll just create a copy of the course.
I have recently tried to learn how to create an object of vectors in order to represent objects of students including their names and grades. but when I wrote my program I got some errors regarding using &. I do not know what is the problem with my errors. could you please help me to fix it?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void printvector(const vector< student>&); // fill vector.fill in student information
void fillvector(vector< student>&); // print the information of all students
class student {
public:
student();
student(string, char);
~student();
string getName() ;
char getGrade() ;
void setName(string);
void setGrade(char);
private:
string newName;
char newGrade;
};
student::student() { newGrade = ' '; }
student::student(string name, char grade) {
newName = name;
newGrade = grade;
}
student::~student(){ }
string student::getName() { return newName; }
char student::getGrade() { return newGrade; }
void student::setName(string name) { newName = name; }
void student::setGrade(char grade) { newGrade = grade; }
int main() {
vector<student> myclass;
printvector(myclass);
fillvector(myclass);
return 0;
}
void fillvector(vector< student>& newmyclass) {
string name;
char grade;
int classsize;
cout << "how many students are in your class?";
cin >> classsize;
for (int i = 0; i < classsize; i++) {
cout << "enter student name";
cin >> name;
cout << "enter student grade";
cin >> grade;
student newstudent(name, grade);
newmyclass.push_back(newstudent);
cout << endl;
}
}
void printvector( vector< student>& newmyclass) {
unsigned int size = newmyclass.size();
for (unsigned int i = 0; i < size; i++) {
cout << "student name:" << newmyclass[i].getName() << endl;
cout << endl;
cout << "student grade" << newmyclass[i].getGrade() << endl;
cout << endl;
}
}
It seems you're printing your vector before filling it.. Is your problem fixed when you swap them around?
int main() {
vector<student> myclass;
printvector(myclass); // <--- These two lines should probably be swapped
fillvector(myclass); // <---
return 0;
}
I wish to output different string for reading variables. For example, below, I wish to print Enter english marks before reading english marks using eng.setmarks(). Please suggest a way to implement this.
Here is my code: (look at for loop below)
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
class student {
char name[20];
int age;
class marks {
int marks;
public:
void setmarks( int x) {
marks = x;
}
int getmarks() {
return marks;
}
};
public:
marks eng, math, phy, chem, cs; // nested objects are public
void setname( char* n) {
strncpy( name, n, 20);
}
char* getname() {
return name;
}
void setage( int a) {
age = a;
}
float total() {
size_t total = eng.getmarks() + math.getmarks() +
phy.getmarks() + chem.getmarks() + cs.getmarks();
return total/500.0;
}
};
int main() {a
student new_stud;
char temp[20];
cout << "Enter name: ";
cin >> temp;
cin.get( temp, sizeof(temp));
new_stud.setname(temp);
int age;
cout << "Enter age: ";
cin >> age;
new_stud.setage( age);
for( size_t i = 0; i < 5; ++i) {
// I wish to output: "Enter marks in" + subject_name, but harcoding it seems tedious
}
cout << "\nTotal Percentage: " << new_stud.total();
return 0;
}
So if I understand correctly, you would like to print out the name of the variable which you are about to read into. Now this can't be done on the way you want it. The best thing you can do is make an array of subject names, and an array of marks.
string[5] Subjects = {"Maths", "English", "Chemistry", "Physiscs", "Computer Sciences"};
marks[5] Marks;
for(int i=0;i<5;i++) {
cout << "Please enter marks in " << Subjects[i] << ":" << endl;
int a;
cin >> a;
Marks[i].setmarks(a);
}
You could also make the marks class have a field subject name, and give it a function inputfromuser(), like this:
class marks {
int marks;
string subjectName;
public:
void setmarks( int x) {
marks = x;
}
int getmarks() {
return marks;
}
void inputfromuser() {
cout << "Please enter marks in " << subjectName << ":" << endl;
cin >> marks;
}
};
Sorry for me using the std::string type, I am not very comfortable with the raw char[] way to handle texts.
This program is supposed to prompt the user for two different employees and print their name, last name, ssn, payrate, and total pay for the week. Also it should determine if the worker worked any over time hours and recalculate their pay if they do.
I keep getting this error message:
No matching function call to Employee::Employee()
I will mark the lines which this message appears with a // *****.
The message appears 3 times. Please review my issues and help me fix them, and also explain what you did to fix them.
#include <cstdlib>
#include <iostream>
#include <math.h>
/*
Name: Employee2
Author: --------
Date: 20/10/14 20:36
Description: A program that prints workers info using classes
*/
using namespace std;
class Employee
{
private:
string firstname, lastname, ssn;
int payRate, hours;
public:
//A Four Parameter Constructor
Employee (string newFirst, string newLast, string newSsn, int newpayRate, int newHours)
{
firstname = newFirst;
lastname = newLast;
ssn = newSsn;
payRate = newpayRate;
hours = newHours;
}
//Setter or Mutator Functions
void setnewFirst(string newFirst)
{
firstname = newFirst;
}
void setnewLast(string newLast)
{
lastname = newLast;
}
void setnewSsn(string newSsn)
{
ssn = newSsn;
}
void setnewpayRate(int newpayRate)
{
payRate = newpayRate;
}
void setnewHours(int newHours)
{
hours = newHours;
}
void setEmployee(string newFirst, string newLast, string newSsn, int newpayRate, int newHours)
{
firstname = newFirst;
lastname = newLast;
ssn = newSsn;
payRate = newpayRate;
hours = newHours;
}
//Accessor Functions
string getfirstname ()
{
return firstname;
}
string getlastname ()
{
return lastname;
}
string getssn ()
{
return ssn;
}
int getpayRate ()
{
return payRate;
}
int gethours ()
{
return hours;
}
//Output Functions
void printEmployee ()
{
cout << firstname << " " << lastname << endl << ssn << endl << payRate << endl << hours << endl;
}
//Functions to use employee info
Employee newEmployee ()
{
Employee e1; //**************
string newFirst;
string newLast;
string newSsn;
int newpayRate;
int newHours;
cout << "Enter First Name: " ;
cin >> newFirst;
cout << "Enter Last Name: " ;
cin >> newLast;
cout << "Enter SSN: " ;
cin >> newSsn;
cout << "Enter Payrate: " ;
cin >> newpayRate;
cout << "Enter Hours Worked: " ;
cin >> newHours;
e1.setnewFirst(newFirst);
e1.setnewLast(newLast);
e1.setnewSsn(newSsn);
e1.setnewpayRate(newpayRate);
e1.setnewHours(newHours);
return e1;
}
//Function to Calculate Weekly Pay
int calculatePay (int hours)
{
double result;
if ( hours > 40 )
{
result = (hours - 40) * (payRate * 1.5) + (40 * payRate);
}
else
{
result = (hours * payRate);
}
}
};
Employee newEmployee();
//Main
int main(int argc, char *argv[])
{
Employee firstEmployee; // *********************
Employee secondEmployee; // *********************
double result;
firstEmployee = firstEmployee.newEmployee();
secondEmployee = secondEmployee.newEmployee();
cout << "First Employee Pay: " ;
firstEmployee.printEmployee();
cout << endl;
cout << "Secnod Employee Pay: " ;
secondEmployee.printEmployee();
system("PAUSE");
return EXIT_SUCCESS;
}
A constructor is intended to operate on the space in which the new object is being created. This means you don't need to complicate things by creating the additional object e1. Remove the problematic line:
Employee e1; //**************
Remove all e1 references from your code; for example change
e1.setnewFirst(newFirst);
e1.setnewLast(newLast);
e1.setnewSsn(newSsn);
e1.setnewpayRate(newpayRate);
e1.setnewHours(newHours);
to:
setnewFirst(newFirst);
setnewLast(newLast);
setnewSsn(newSsn);
setnewpayRate(newpayRate);
setnewHours(newHours);
Constructors do not return values; remove:
return e1;
Compile, test, debug, rinse, and repeat.
class Student
{
private:
string name;
int year;
string semester;
int AmtClass;
static string Year[4];
public:
Student();
Student(int AmtClass);
Student(Student &);
void setName(string name);
void setYear(int year);
void setSemester(string semester);
void setAmtClass(int AmtClass);
string getName();
int getYear();
string getSemester();
int getAmtClass();
~Student()
{
if(AmtClass > 0)
delete [] course;
}
};
string Student::Year[4] = { "Freshman", "Sophomore", "Junior", "senior" };
Student::Student()
{
name = "";
year = 0;
semester = "";
AmtClass = 0;
}
Student::Student(int amount)
{
AmtClass = amount;
string *pName;
pName = new string[AmtClass];
for(int i = 0; i < AmtClass; i++)
{
pName[i] = "";
}
}
Skipping Accessors and Mutator functions...
void readStudentData(Student &);
void printStudentData(Student);
int main()
{
int amount;
cout << "How many courses are you currently taking? ";
cin >> amount;
Student kid;
kid.setAmtClass(amount);
readStudentData(kid);
}
void readStudentData(Student &kid)
{
cin.ignore(10000, '\n');
int amount = kid.getAmtClass();
string name = "";
string semester = "";
int year = 0;
cout << "What is your full name? ";
getline(cin,name);
cout << "\nHow many years have you been in college? ";
cin >> year;
cout << "\nWhat is your current semester? ";
getline(cin,semester);
Student kid1(amount);
cout << "Please enter the name of all your courses." << endl;
for(int i = 0; i < amount; i++)
{
cout << "Course #" << i+1 << " : ";
getline(cin,pName[i]);
}
}
Okay edited this program a bit after realizing my pName is a local variable in the constructor...I am supposed to create a constructor that received an integer parameter corresponding to the number of courses the student is taking.The function dynamically allocates the string array of courses and sets each element to "". And then I am supposed to use this to record the names of the courses the student is taking.
The Year array should simply be allocated to the amount, and that's it:
Student::Student(int amount)
: Year(new std::string[amount]()), AmtClass(amount)
{
}
You can also use std::vector for this so you do not have to deal with deleting the memory yourself:
class Student
{
std::vector<std::string> Year;
// ...
};
Student::Student(int amount)
: Year(amount), AmtClass(Year.size())
{
}