C++ do/while loop and calling functions? - c++

I am having trouble trying to get this program to loop if user enter 'y' they'd like to continue. I'm super new to programming by the way so any help is greatly appreciated. I figured the best was to add a do/while in main and as k the user if they'd like to continue at the end of the code but, I quickly realized that wouldn't work unless I called the previous methods for user input and output. That's where the issue is arising.
Thanks again for any help!
/*
• Ask the user if they want to enter the data again (y/n).
• If ’n’, then the program ends, otherwise it should clear the student class object and
repeat the loop (ask the user to enter new data...).
*/
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class Student {
public:
Student();
~Student();
void InputData(); // Input all data from user
void OutputData(); // Output class list to console
void ResetClasses(); // Reset class list
Student& operator =(const Student& rightSide); // Assignment operator
private:
string name;
int numClasses;
string *classList;
};
//array intialized to NULL
Student::Student() {
numClasses = 0;
classList = NULL;
name = "";
}
//Frees up any memory of array
Student::~Student() {
if(classList != NULL) {
delete [] classList;
}
}
// This method deletes the class list
// ======================
void Student::ResetClasses() {
if(classList != NULL) {
delete [ ] classList;
classList = NULL;
}
numClasses = 0;
}
//inputs all data from user (i.e. number of classes)
//using an array to store classes
void Student::InputData() {
int i;
// Resets the class list in case the method
// was called again and array wasn't cleared
ResetClasses();
cout << "Enter student name." << endl;
getline(cin, name);
cout << "Enter number of classes." << endl;
cin >> numClasses;
cin.ignore(2,'\n'); // Discard extra newline
if (numClasses > 0) {
//array to hold number of classes
classList = new string[numClasses];
// Loops through # of classes, inputting name of each into array
for (i=0; i<numClasses; i++) {
cout << "Enter name of class " << (i+1) << endl;
getline(cin, classList[i]);
}
}
cout << endl;
}
// This method outputs the data entered by the user.
void Student::OutputData() {
int i;
cout << "Name: " << name << endl;
cout << "Number of classes: " << numClasses << endl;
for (i=0; i<numClasses; i++) {
cout << " Class " << (i+1) << ":" << classList[i] << endl;
}
cout << endl;
}
/*This method copies a new classlist to target of assignment. If the operator isn't overloaded there would be two references to the same class list.*/
Student& Student::operator =(const Student& rightSide) {
int i;
// Erases the list of classes
ResetClasses();
name = rightSide.name;
numClasses = rightSide.numClasses;
// Copies the list of classes
if (numClasses > 0) {
classList = new string[numClasses];
for (i=0; i<numClasses; i++) {
classList[i] = rightSide.classList[i];
}
}
return *this;
}
//main function
int main() {
char choice;
do {
// Test our code with two student classes
Student s1, s2;
s1.InputData(); // Input data for student 1
cout << "Student 1's data:" << endl;
s1.OutputData(); // Output data for student 1
cout << endl;
s2 = s1;
cout << "Student 2's data after assignment from student 1:" << endl;
s2.OutputData(); // Should output same data as for student 1
s1.ResetClasses();
cout << "Student 1's data after reset:" << endl;
s1.OutputData(); // Should have no classes
cout << "Student 2's data, should still have original classes:" << endl;
s2.OutputData(); // Should still have original classes
cout << endl;
cout << "Would you like to continue? y/n" << endl;
cin >> choice;
if(choice == 'y') {
void InputData(); // Input all data from user
void OutputData(); // Output class list to console
void ResetClasses(); // Reset class list
}
} while(choice == 'y');
return 0;
}

Just get rid of
if(choice == 'y') {
void InputData(); // Input all data from user
void OutputData(); // Output class list to console
void ResetClasses(); // Reset class list
}
Because the variables s1 and s2 are inside the do-while loop, they'll be recreated on each iteration. (The constructor will be called at the definition, and the destructor will be called at the closing brace of the loop, before it tests choice == 'y' and repeats).
The other problem you run into is that your standard input isn't in a state compatible with calling s1.InputData() again. Because you just used the >> extraction operator to read choice, parsing stopped at the first whitespace, and there is (at least) a newline leftover in the buffer. When Student::InputData calls getline, it will find that newline still in the buffer and not wait for additional input.
This is the same reason you used cin.ignore after reading numClasses. You'll want to do the same here.

Related

How to store an instance of class in a vector?

I have made a class for a student with course and grade, the program keeps asking for a new student until the name given is stop. To store these instances I want to use a vector, but I didn't find any other way to store them than creating an array for the instances first and then pushing them back into the vector.
Is it possible to have room for one instance and delete the values stored in Student student after use so it can be reused?
int i=0;
Student student[20];
vector<Student> students;
cout << "Name?" << endl;
getline(cin,student[i].name);
while((student[i].name) != "stop")
{
student[i].addcoursegrade();
students.push_back(student[i]);
i++;
cout << "Name?" << endl;
getline(cin,student[i].name);
if((student[i].name) == "stop")
break;
};
I also use vectors inside the class to store the values for course and grade, since they are also supposed to be growing. The code for the class is here:
class Student {
public:
string name;
void print() {
cout << name ;
for (int i = 0; i < course.size(); i++)
cout << " - " << course[i] << " - " << grade[i];
cout<<endl;
}
void addcoursegrade() {
string coursee;
string gradee;
cout << "Course?" << endl;
getline(cin, coursee);
course.push_back(coursee);
while (coursee != "stop") {
cout << "Grade?" << endl;
getline(cin, gradee);
grade.push_back(gradee);
cout << "Course?" << endl;
getline(cin, coursee);
if (coursee != "stop")
course.push_back(coursee);
else if(coursee == "stop")
break;
}
};
private:
vector<string> course;
vector<string> grade;
};
Instead of creating an array then pushing back, simply keep one instance around and reassign it:
Student student;
vector<Student> students;
cout << "Name?" << endl;
getline(cin,student.name);
while((student.name) != "stop")
{
student.addcoursegrade();
// this line copies the student in the vector
students.push_back(student);
// then, reassign the temp student to default values
student = {};
cout << "Name?" << endl;
getline(cin,student.name);
if((student.name) == "stop")
break;
};
A few things bothered me:
The way your loops were structured, duplicating the getline. I prefer a while(true) array with a break when the terminating input appears.
No need for a C-style array. std::vector is the way!
separate arrays for course and grade. Instead, I prefer a single record that stores both the course and the grade
indices in your loops that are only used to access the items within the collection. (Just use a range-based for loop)
Don't make a Student object until you need to. Use local variables for string inputs.
As with anything in C++, lots more could be done do to improve it: things like add constructors for your objects, initialize with modern syntax, embrace move semantics, etc. But I'm just making minimal changes.
I'd tackle it like this:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
struct CourseGrade {
string course;
string grade;
};
class Student {
public:
string name;
void print() {
cout << name;
for (auto& courseGrade : courseGrades) {
cout << " - " << courseGrade.course << " - " << courseGrade.grade;
}
cout << endl;
}
void addcoursegrades() {
while (true) {
cout << "Course?" << endl;
string course;
getline(cin, course);
if (course == "stop") break;
cout << "Grade?" << endl;
string grade;
getline(cin, grade);
CourseGrade courseGrade;
courseGrade.course = course;
courseGrade.grade = grade;
courseGrades.push_back(courseGrade);
}
}
private:
vector<CourseGrade> courseGrades;
};
int main() {
vector<Student> students;
while (true) {
cout << "Name?" << endl;
std::string name;
getline(cin, name);
if (name == "stop") break;
Student student;
student.name = name;
student.addcoursegrades();
students.push_back(student);
};
for (auto& student : students) {
student.print();
}
}

C++ Program with clasess

I'm trying to make a program and while I'm making it I'm learning classes, inheritance and things I'll need. I'll give you the condition of the program and the code to where I got to.
The 2nd class I made it inherit the 1st, but I can't get the console to return the student's grade. Тhe condition they gave me confuses me and I can't figure out how they want to calculate the student's grade? Thanks in advance for your time and kindness :)
I. Define a student class CStudent storing name information,
student's faculty number and major to provide:
Create objects using a copy constructor
Creation of objects by explicit constructor (with parameters)
Using an implicit constructor
Assignment operator =
Comparison operator ==
Comparison operator < (by faculty number)
To read student data from stream input - operator>>
To output the student data to stream output - operator<<
Establish the member variables (mutators)
Reading the member variables (accessors)
II. Define a student booklet class CStudBook that inherits
CStudent with a member data container of the student's grades. To implement
a constructor with a filename parameter from which to initialize
container and the following methods:
Create an object using another object (copy constructor)
Creating an object using explicit parameters
Creating an object by default constructor
Calculate and return the student's grade point average
operator>>
operator<<
Print
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
class CStudent {
public:
// Default constructor
CStudent() = default;
// Explicit constructor
CStudent(string name, int facnum, string specialty) {
this->name = name;
this->facnum = facnum;
this->specialty = specialty;
}
// Copy constructor
CStudent(const CStudent& obj) {
this->name = obj.name;
this->facnum = obj.facnum;
this->specialty = obj.specialty;
}
// Method, that prints the contents of the object
void PrintStudent() const {
cout << "Name: " << name << endl;
cout << "Fac. num: " << facnum << endl;
cout << "Specialty: " << specialty << endl;
}
friend std::ostream& operator <<(std::ostream& out, const CStudent& obj) // output operator
{
out << "Name:" << obj.name << "-> FacNumber: " << obj.facnum << std::endl;
}
bool operator <(const CStudent& obj) // operator for comparison of two objects
{
return name < obj.name;
return facnum < obj.facnum;
}
// operator login should be added here
private:
string name;
int facnum;
string specialty;
};
class CStudBook : public CStudent {
private:
int grade;
};
// Function, that gets student data from the console
// and creates an instance of the CStudent class using this data
CStudent CreateFromConsole() {
cout << "Enter name: ";
string name;
cin >> name;
cout << "Enter fac. num: ";
int facnum;
cin >> facnum;
cout << "Enter specialty: ";
string specialty;
cin >> specialty;
cout << "Enter student grade: ";
int grade;
cin >> grade;
cout << endl;
return CStudent(name, facnum, specialty); // returns an instance of the class
}
int main() {
vector<CStudent> students; // stack-like container
cout << "Enter total number of students: ";
int count;
cin >> count;
cout << "Enter details of students" << endl << endl;
for (int i = 0; i < count; i++) {
// Create an instance of the class
CStudent student = CreateFromConsole();
// Push a copy of the object into the container
students.push_back(student);
}
cout << endl;
cout << "Details" << endl << endl;
for (int i = 0; i < students.size(); i++) {
students[i].PrintStudent();
cout << endl;
}
fflush(stdin); // Reset input console
getchar(); // Pause
return 0;
}
I think grade is private members of class CStudBook so you can't call it from class CStudent.
If you want to access it my suggested keyword for you to find is protected members

Error:C2679 binary '==': no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion

I have written my code for an employee management system that stores Employee class objects into a vector, I am getting no errors until I try and compile, I am getting the error: C2679 binary '==': no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion). But I am not sure why any help would be great, Thank you!
// Employee Management System
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Employee
{
public:
Employee();
string GetName();
string GetStatus();
float GetSalary();
int GetAge();
int GetYearHired();
private:
string m_Name;
string m_Status;
float m_Salary;
int m_Age;
int m_YearHired;
};
Employee::Employee()
{
m_Salary = 0;
m_Age = 0;
m_YearHired = 0;
}
string Employee::GetName()
{
string fName;
string lName;
cout << "Please enter the new employee's first name: ";
cin >> fName;
cout << "Please enter the new employee's last name: ";
cin >> lName;
m_Name = fName + lName;
return m_Name;
}
string Employee::GetStatus()
{
string status;
cout
<< "Please enter the employee's status (full time, part time, or manager): ";
cin >> status;
return m_Status;
}
float Employee::GetSalary()
{
float salary;
cout << "Please enter the employee's salary: ";
cin >> salary;
return m_Salary;
}
int Employee::GetAge()
{
int age;
while (true)
{
cout << "Please enter the employee's age: ";
cin >> age;
if (age > 0)
break;
else
cout << "Error: Please enter a positive value.";
}
return m_Age;
}
int Employee::GetYearHired()
{
int yearHired;
cout << "Please enter what year the employee was hired: ";
cin >> yearHired;
return m_YearHired;
}
class Staff
{
vector<Employee*> emps;
vector<Employee*>::const_iterator iter;
public:
Staff();
virtual ~Staff();
void Add();
void Remove();
void Clear();
void Display();
};
Staff::Staff()
{
emps.reserve(20);
}
Staff::~Staff()
{
Clear();
}
void Staff::Add()
{
Employee* emp = new Employee;
emp->GetName();
emp->GetStatus();
emp->GetSalary();
emp->GetAge();
emp->GetYearHired();
emps.push_back(emp);
}
void Staff::Remove()
{
Employee* emp;
cout << "Which employee would you like to remove?";
emp->GetName();
iter = find(emps.begin(), emps.end(), emp->GetName()); // Trying to find the employee in the datbase.
if (iter != emps.end()) // If the employee is found in the vector it is removed.
{
cout << "\n" << *iter << " was removed\n\n";
emps.erase(iter); // removes employee from the vector.
}
else // If the employee is not found in the vector, it tells the user that the employee was not found.
{
cout << "Employee not found, please choose anoter employee.\n\n";
}
}
void Staff::Clear()
{
cout << "\nDo you really want to clear all employees? (yes/no)\n"; // Asking the user if they want to clear the database.
string response;
// Storing the response of the user.
cin >> response; // Getting the users response (yes/no).
if (response == "yes") // If response is yes.
{
vector<Employee*>::iterator iter = emps.begin(); // Declares an iterator for the emps vector and sets it to the beginning of the vector.
for (iter = emps.begin(); iter != emps.end(); ++iter) // Iterates through vector.
{
delete *iter; // Deletes the iterators in the vector, freeing all memory on the heap.* iter = 0;
// Sets iterator to zero so it does not become a dangling pointer.
}
emps.clear(); // Clear vector of pointers.
}
else // If response is no.
{
cout << "\nAll employee's remain in the database.\n";
}
}
void Staff::Display()
{
Employee* emp;
if (emps.size() == 0) // Checking to see if the database is empty.
cout
<< "\nThere are no employee's in the database, add employee's to view them here.\n ";
else // If the cart contains any items.
{
cout << "\nThe database contains: \n";
for (iter = emps.begin(); iter != emps.end(); ++iter) // Displaying the inventory.
{
cout << "-------------------------------------------------";
cout << "Employee's Name : " << emp->GetName() << endl;
cout << "Employee's Status : " << emp->GetStatus() << endl;
cout << "Employee's Salary : " << emp->GetSalary() << endl;
cout << "Employee's Age : " << emp->GetAge() << endl;
cout << "Year employee was hired : " << emp->GetYearHired() << endl;
cout << "-------------------------------------------------";
}
}
}
int main()
{
int option = 0;
Staff stf;
// Welcoming the user to the Employee Management System program.
cout
<< "Welcome to our Employee Management System! To get started see the menu options below :\n ";
// Main loop
while (option != 5) // The loop will repeat until the user enters 5 as the option.
{
cout << "------------------------------------------------------------------------------------- - ";
cout << "\nMenu Options: \n";
cout << "\nTo select an option, please type in the number that corresponds to that option.\n ";
cout << "1 - Add an Employee\n2 - Remove an Employee\n3 - Clear the database\n4 - Display Employee's in Database\n5 - Quit" << endl;
cout << "\nWhat would you like to do? ";
cout << "------------------------------------------------------------------------------------- - ";
// Start of the validity check.
bool validInput = false;
while (!validInput) // The loop will repeat until the users input is valid.
{
cin >> option; // User inputs first option choice.
validInput = true; // Assign the input as valid.
if (cin.fail()) // Tests to make sure the value assigned is valid for the variable type.
{
cout << "\nPlease choose a menu option by number\n";
cin.clear(); // Clears stream error.
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Removes an invalid characters.
validInput = false; // Sets the input back to false, repeats the loop.
}
}
switch (option)
{
case 1:
{
stf.Add();
break;
}
case 2:
{
stf.Remove();
break;
}
case 3:
{
stf.Clear();
break;
}
case 4:
{
stf.Display();
break;
}
case 5: // If option = 5.
cout << "\nThank you for using the Employee Management Program!\n";
// Thanks the user for using the Employee Management program.
break;
default: // If the user does not put in a valid option, it tells them to try again.
cout << "\nThat's not a valid option. Please try again.\n";
break;
}
}
system("pause");
return 0;
}
Problem
std::find is going to compare the Employee *s in emps against the std::string that is returned by GetName. There is no comparison operator defined for Employee * that does this. We can make one, but because the behaviour of GetName is to Get and name for the user, not simply return the Employee's name this will quickly become a mess.
Solution
First Stop storing pointers to Employees in the vectors. This simple change will eliminate the vast majority of your past, present and future pain. In general, use new as little as possible (Why should C++ programmers minimize use of 'new'?) and when you do find yourself needing new, prefer a smart pointer.
vector<Employee*> emps;
becomes
vector<Employee> emps;
that has a ripple effect through your code, not the least of which is
void Staff::Add()
{
Employee* emp = new Employee;
emp->GetName();
emp->GetStatus();
emp->GetSalary();
emp->GetAge();
emp->GetYearHired();
emps.push_back(emp);
}
must become
void Staff::Add()
{
Employee emp;
emp.GetName();
emp.GetStatus();
emp.GetSalary();
emp.GetAge();
emp.GetYearHired();
emps.push_back(emp);
}
But also look into emplace_back and strongly consider getting the user input and then constructing emp around it.
bool operator==(const Employee & rhs) const
{
return m_Name == rhs.m_Name;
}
or a friend function
bool operator==(const Employee & lhs,
const Employee & rhs)
{
return lhs.m_Name == rhs.m_Name;
}
and then change the call to find to compare Employees
iter = find(emps.begin(), emps.end(), emp); // Trying to find the employee in the datbase.
This may lead to more problems because iter is a const_iterator and a member variable (Rubber Ducky wants a word with you about this). Also completely ignores the fact that there are a few dozen more logical mistakes in the the code.
It seems to me (EDIT: had a commented out) string response; declaration before
cin >> response; // Getting the users response (yes/no).
Hope this points you in the right direction
EDIT:
It's there but it's commented out. Try:
cout << "\nDo you really want to clear all employees? (yes/no)\n";
// Asking the user if they want to clear the database.
string response;
// Storing the response of the user.
cin >> response; // Getting the users response (yes/no).
if (response == "yes") // If response is yes.
And I'd double check all the code to avoid the comments interfering with the code

C++ function in switch statement is not executing

I'm new to c++ and I'm trying to make a simple class roster program that accepts new students storing the student data in an array that then be sorted and display the contents of the array. However when running the program and entering the menu selection, two of the three functions do not work. Any help or guidance is much appreciated. My code is here.
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
using namespace std;
//Create Students class
class Students
{
public:
char sFirstName[256];
char sLastName[256];
int sStudentID;
double sGrade;
double sGPA;
double nCreditHours;
};
//functions
Students addStudent();
//void displayRoster();
//void sortRoster();
void showMenu();
void showWelcome();
//Welcome function
void showWelcome()
{
cout << "Welcome to my class roster program. \n"
<< "This program can be used to add students to the roster, \n"
<< "which can then be sorted by either name or I.D. number. \n"
<< endl;
}
//Menu function
void showMenu()
{
cout << " Student Roster: \n"
<< "MAIN MENU PLEASE SELECT AN OPTION" << endl;
cout << "1) Add student to roster: " << endl;
cout << "2) Display current roster: " << endl;
cout << "3) Sort roster: " << endl;
cout << "4) Exit program: " << endl;
//cout << "5) Display roster sorted by 'student I.D.': " << endl;
//cout << "6) Display roster sorted by 'Grade': " << endl;
//cout << "7) Display roster sorted by 'GPA': \n" << endl;
cout << " Make your selection: \n" << endl;
}
//Add student function
Students addStudent()
{
Students student;
cout << "Add student to roster. \n"
<< "Enter first name: " << endl;
cin >> student.sFirstName;
cout << "Enter last name: " << endl;
cin >> student.sLastName;
cout << "Enter student I.D.: " << endl;
cin >> student.sStudentID;
return student;
}
void displayStudent(Students student)
{
cout << "Student name: " << student.sFirstName << " "
<< student.sLastName << endl;
cout << "I.D. # " << student.sStudentID << endl;
}
void displayRoster()
{
Students student[256];
int nCount;
for (int index = 0; index < nCount; index++)
{
displayStudent(student[index]);
}
}
int getStudents(Students student[], int nMaxSize)
{
int index;
for (index = 0; index < nMaxSize; index++)
{
char uInput;
cout << "Enter another student to the roster? (Y/N): ";
cin >> uInput;
if (uInput != 'y' && uInput != 'Y')
{
break;
}
student[index] = addStudent();
}
return index;
}
void sortRoster()
{
Students student[256];
int nCount;
//bubble swap
int nSwaps = 1;
while (nSwaps != 0)
{
nSwaps = 0;
for (int n = 0; n < (nCount - 1); n++)
{
if (student[n].sStudentID > student[n+1].sStudentID)
{
Students temp = student[n+1];
student[n+1] = student[n];
student[n] = temp;
nSwaps++;
}
}
}
}
int main()
{
int selection; //menu selection variable
//constants for menu selection
const int ADD_STUDENT = 1,
DISPLAY_ROSTER = 2,
SORT_ROSTER = 3,
QUIT_PROGRAM = 4;
Students student[256];
//int nCount = getStudents(student, 256);
do
{
showWelcome(); //Show welcome message
showMenu(); //Show menu options
cin >> selection;
while (selection < ADD_STUDENT || selection > QUIT_PROGRAM)
{
cout << "Enter a valid selection: ";
cin >> selection;
}
if (selection != QUIT_PROGRAM)
{
switch (selection)
{
case ADD_STUDENT:
addStudent();
break;
case DISPLAY_ROSTER:
displayRoster();
break;
case SORT_ROSTER:
sortRoster();
break;
}
}
}
while (selection != QUIT_PROGRAM);
return 0;
}
The problem is not in the switch.
The addStudent() is not adding the student into any list or array. Also since it return type is Students you should add it into the any array of Students. Since you have not stored any data display won't display anything.
The another problem is of nCount. You are using it in for comparison without initializing it. Also to keep nCount synchronized either make it global, use as pointer or handle it with return.
Also the problem is in displayRoster(). You are declaring Students array as Students student[256]; and you are using it without initializing. Also if initialized, it won't have the data which was given as input.
NOTE: Sit and read your code again, there are many more mistakes. Try visualizing how your data should be stored and how your code is to behave and then start writing code.
Your nCount is not initialised. Since this variable is used in those two functions (and assuming that it refers to the total count), you can declare it as a global variable:
nCount=0;
Everytime you add a new entry, you can increment the counter as:
nCount++;
Another suggestion to make your code actually work:
student[i++]=addStudent();
where i is a counter initialised to 0. Your addStudent() function returns an object, and you discard it. Store it in the array of objects you created:
Students student[256];
Also, since you use the above in almost all functions, it is best to declare it as global rather than redeclaring in each function.

C++ discard the leftover newline from input buffer issue

I am trying to get this assignment down for a c++ class. I had issues with the do/while loop not working correctly and someone suggested adding the line cin.ignore(2,'\n'); in the InputData function under where the enter student name is being asked by the user. That worked and the do/while is now working. However, I'm not 100% sure how the cin.ignore(2,'\n'); works and I have an issue during the first go around where the first two characters of the "name" that the user inputs is getting discarded. If I change that 2 to a 0 it it doesn't cut off the first two characters of the name but if the user enters 'y' they'd like to continue, the program skips the first question "Enter the name of the student".
Any help is greatly appreciated!!
FYI, I am super new to programming in general, especially c++. Be nice please lol.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class Student {
public:
Student();
~Student();
// Input all info of user
void InputData();
// Output class list
void OutputData();
// Reset class list
void ResetClasses();
Student& operator =(const Student& rightSide);
private:
string name;
string stuName;
int numbClasses;
string *classList;
};//end student class
//Initialize variables to empty and array to NULL
Student::Student() {
numbClasses = 0;
classList = NULL;
name = "";
}//end variable initialization
//Frees up any memory allocated to array.
Student::~Student() {
if (classList != NULL) {
delete [ ] classList;
}//end if
}//end free memory
//Delete the class list
void Student::ResetClasses() {
if (classList != NULL) {
delete [] classList;
classList = NULL;
}//end if block
numbClasses = 0;
}//end reset classes
Here is where the line cin.ignore(2,'\n'); is located
// Inputs info from user.
void Student::InputData() {
int i;
// Reset the class list in case method is called again and array isn't cleared
ResetClasses();
cout << "Enter student name." << endl;
//Discards the leftover newline from input buffer
cin.ignore(2,'\n');
getline(cin, name);
cout << "Enter number of classes." << endl;
cin >> numbClasses;
//Discards the leftover newline from input buffer
cin.ignore(2,'\n');
if (numbClasses > 0) {
// Construct array big enough to hold # of classes
classList = new string[numbClasses];
// Loop through the # classes, input name of each one into array
for (i = 0; i < numbClasses; i++) {
cout << "Enter name of class " << (i+1) << endl;
getline(cin, classList[i]);
}//end for loop
}//end if block
cout << endl;
}//end input data
Output data
//Output info entered by user.
void Student::OutputData() {
int i;
cout << "Name: " << name << endl;
cout << "Number of classes: " << numbClasses << endl;
for (i=0; i<numbClasses; i++) {
cout << " Class " << (i+1) << ":" << classList[i] << endl;
}//end for loop
cout << endl;
}//end Output data
//overload this operator so there aren't two references to same class list.
Student& Student::operator =(const Student& rightSide) {
int i;
// Erase list of classes
ResetClasses();
name = rightSide.name;
numbClasses = rightSide.numbClasses;
// Copy the list of classes
if (numbClasses > 0) {
classList = new string[numbClasses];
for (i=0; i<numbClasses; i++) {
classList[i] = rightSide.classList[i];
}//end for loop
}//end if block
return *this;
}//end overload
Main, where the do/while loop is located.
// main function
int main() {
char choice;
//Do/While loop to ask user if they'd like to continue or end program.
do {
// Test code with two student classes
Student s1, s2;
// Input for s1
s1.InputData();
cout << "Student 1's data:" << endl;
// Output for s1
s1.OutputData();
cout << endl;
s2 = s1;
cout << "Student 2's info after assignment from student 1:" << endl;
// Should output same info as student 1
s2.OutputData();
s1.ResetClasses();
cout << "Student 1's info after the reset:" << endl;
// Should have no classes
s1.OutputData();
cout << "Student 2's info, should still have original classes:" << endl;
// Should still have original classes
s2.OutputData();
cout << endl;
cout << "Would you like to continue? y/n" << endl;
cin >> choice;
} while(choice == 'y'); //end do/while
return 0;
}//end main
I recommend you remove all the cin.ignore(2,'\n'); statements and instead skip the whitespace (spaces and returns) immediately before you use std::getline(). You can do this with the std::ws manipulator: see: std::ws
So your std::getline() statements become:
getline(cin >> std::ws, name); // NOTE: >> std::ws skips whitespace
So like this:
// Inputs info from user.
void Student::InputData() {
int i;
// Reset the class list in case method is called again and array isn't cleared
ResetClasses();
cout << "Enter student name." << endl;
//Discards the leftover newline from input buffer
//cin.ignore(2,'\n');
getline(cin >> std::ws, name); // NOTE: >> std::ws skips whitespace
cout << "Enter number of classes." << endl;
cin >> numbClasses;
//Discards the leftover newline from input buffer
//cin.ignore(2,'\n');
if (numbClasses > 0) {
// Construct array big enough to hold # of classes
classList = new string[numbClasses];
// Loop through the # classes, input name of each one into array
for (i = 0; i < numbClasses; i++) {
cout << "Enter name of class " << (i+1) << endl;
getline(cin >> std::ws, classList[i]); // NOTE: >> std::ws skips whitespace
}//end for loop
}//end if block
cout << endl;
}//end input data