How can I solve this pointer/memory issue? - c++

I trying to write a program that asks the user for movie information. stores the information of a movie as a struct in a vector and then output the result to the screen with the 2 functions having a return type of void.
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
using namespace std;
void make_movie(struct movie *film);
void show_movie(vector <movie> data, int cnt);
struct movie {
string name;
string director;
int year;
int duration;
};
int main() {
int count = 0;
char input;
vector <movie> record;
movie *entry = nullptr;
do {
make_movie(entry);
record.push_back(*entry);
count++;
cout << endl;
cout << "Do you have more movie info to enter?\n";
cout << "Enter y / Y for yes or n / N for no: ";
cin.ignore();
cin >> input;
cout << endl;
} while (input == 'y' || input == 'Y');
show_movie(record, record.size());
return 0;
}
void make_movie(struct movie *film) {
cout << "Enter the title of the movie: ";
cin.ignore();
getline(cin, film -> name);
cout << "Enter the director's name: ";
cin.ignore();
getline(cin, film -> director);
cout << "Enter the year the movie was created: ";
cin >> film -> year;
cout << "Enter the movie length (in minutes): ";
cin >> film -> duration;
}
void show_movie(vector <movie> data, int cnt) {
cout << "Here is the info that you entered: " << endl;
for (int i = 0; i < cnt; i++) {
cout << "Movie Title: " << data[i].name << endl;
cout << "Movie Director: " << data[i].director << endl;
cout << "Movie Year: " << data[i].year << endl;
cout << "Movie Length: " << data[i].duration << endl;
cout << endl;
}
}
I am getting a error that says that i am trying to access a prohibited memory address.

The least amount of changes you need to make is to change:
movie *entry = nullptr;
do {
make_movie(entry);
record.push_back(*entry);
to:
movie entry;
do {
make_movie(&entry);
record.push_back(entry);
Further improvements would be:
Change make_movie to accept parameter by reference, then your program does not use any pointers and therefore is not vulnerable to any of the problems associated with pointers.
Change make_movie to return by value instead of taking a reference parameter.
cin.ignore(); is being used incorrectly. Your program will lose the first character of several of the input strings. Instead, remove all of those calls, and at the end of the make_movie function, ignore the rest of the current line. Also, change cin >> input; to use getline.

your bug
movie *entry = nullptr;
and
you have extra cin.ignore();
cout << "Enter the title of the movie: ";
// cin.ignore();
getline(cin, film -> name);
cout << "Enter the director's name: ";
// cin.ignore();
getline(cin, film -> director);
how to fix
movie main_info;
movie* entry = &main_info;
test
intput:
Enter the title of the movie: any_thing
Enter the director's name: yourself
Enter the year the movie was created: 2016
Enter the movie length (in minutes): 120
Do you have more movie info to enter?
Enter y / Y for yes or n / N for no: n
output
Here is the info that you entered:
Movie Title: any_thing
Movie Director: yourself
Movie Year: 2016
Movie Length: 120

Related

My program is not correctly outputting the amount of students in my struct

i am making a program which is supposed to collect input from the user by asking for id, name, units attempted, units earned and the gpa of a student and store that into a struct. Currently, when i input more than one student into the struct, it only outputs the last student in the array. What can i do to fix this?
Here is my code
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct Student {
string ID; //an 8-digit student ID
string name; //name of the student
unsigned unitsAttempted;//number of units attempted by the student
unsigned unitsEarned; //number of units earned by the student
double gpa; //the grade point average for the student
};
int main()
{
Student students[10];//array for 10 Student Structs
char answer = 'y';
int number = 0;
while ((answer == 'y') || (answer == 'Y')) {
//prompt the user to enter the data
{
answer = ' ';
int i = 0;
cout << "Enter the students ID: \n" ;
getline(cin, students[i].ID);
cout << "\nEnter the name:\n";
getline(cin, students[i].name);
cout << "\nEnter the units attempted:\n";
cin >> students[i].unitsAttempted;
cin.ignore();
cout << "\nEnter the units earned:\n";
cin >> students[i].unitsEarned;
cin.ignore();
cout << "\nEnter the GPA: \n";
cin >> students[i].gpa;
cin.ignore();
cout << "\nWould you like to add another student? y or n\n";
cin >> answer;
cin.ignore();
i++;
number++;
}
}
cout << left << setw(10) << "ID " << setw(20) <<"Name" << setw(20) <<"Units Attempted" << setw(20) <<"Units Earned" << setw(10) <<"GPA";
cout << "\n===============================================================\n";
for (int i = 0; i < number; i++)//display the students
{
cout << left << setw(10) << students[i].ID << setw(20) << students[i].name << setw(20) <<students[i].unitsAttempted << setw(20) <<students[i].unitsEarned << setw(10) <<students[i].gpa << endl << endl;
}
return 0;
}
Im still learning so please go easy on me, thanks.
Currently, when i input more than one student into the struct, it only outputs the last student in the array.
It looks most likely that the scope of your i is incorrect:
int i = 0; //<-- this should be declared outside the `while` loop
As it stands, your i is scoped inside while loop, so it will be reset every time the while loop is entered. In other word, that i never increased.

Pulling data from a structure?

i currently have this code
struct Students {
int studentID;
char firstName[12];
char lastName[12];
char email[25];
};
void showStudentAddMenu()
{
int i;
cout << "How many students would you like to add? (Max 10) ";
cin >> addStudentNumber;
Students student[10];
for (i = 0; i < addStudentNumber; i++)
{
cout << "Student ID: ";
cin >> student[i].studentID;
cout << "Students first name: ";
cin >> student[i].firstName;
cout << "Student last name: ";
cin >> student[i].lastName;
cout << "Student email: ";
cin >> student[i].email;
}
}
void studentLookup()
{
Students student[10];
for (int i = 0; i < 10; i++)
{
cout << "Student ID: " << student[i].studentID << endl;
cout << "Student first name: " << student[i].firstName << endl;
cout << "Student last name: " << student[i].lastName << endl;
cout << "Student email: " << student[i].email << endl;
}
}
int main()
{
do
{
showMainMenu();
cin >> selector;
if (selector == 1)
{
showStudentAddMenu();
}
else if (selector == 2)
{
studentLookup();
}
else if (selector == 3)
{
}
else if (selector == 4)
{
}
else if (selector == 5)
{
exit(0);
}
} while (selector != 5);
return 0;
}
but I'm struggling to pull the data from the structure itself, I just have a bunch of random characters being returned after I input a users data, and try to pull it.
Student ID: -858993460
Student first name: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ɺm0ê²V
Student last name: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ɺm0ê²V
Student email: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ɺm0ê²V
I have a feeling I need to include pointers somehow but I am completely lost and any help would be appreciated, thanks!
From my gesture, you've called all the 10 students struct, since not all of them are filled by the user, it shows some garbage. I've made a dynamic program which reads the limit by the user and defines the arrayed struct.
Look at the following code:
#include <iostream>
const int MAX = 10;
int limit = 0;
struct Students {
int studentID;
string firstName;
string lastName;
string email;
} student[MAX];
void addStudentsPrompt(void);
void studentLookup(void);
int main(void) {
addStudentsPrompt();
studentLookup();
return 0;
}
void addStudentsPrompt(void) {
std::cout << "How many students to register? (Max 10) ";
std::cin >> limit;
for (int i = 0; i < limit; i++) {
std::cout << "Student ID: ";
std::cin >> student[i].studentID;
std::cout << "Students first name: ";
std::cin >> student[i].firstName;
std::cout << "Student last name: ";
std::cin >> student[i].lastName;
std::cout << "Student email: ";
std::cin >> student[i].email;
std::cout << std::endl;
}
}
void studentLookup(void) {
int getSize = sizeof(student) / sizeof(student[0]);
for (int i = 0; i < limit; i++) {
std::cout << "Student ID: " << student[i].studentID << std::endl
<< "Student first name: " << student[i].firstName << std::endl
<< "Student last name: " << student[i].lastName << std::endl
<< "Student email: " << student[i].email << std::endl << std::endl;
}
}
Simply two void functions used which sets and gets the data defined by the user. I recommend you using the string rather than applying character array for better results as I've done in the above code.
Example Output
// --- stdin ---
How many students to register? (Max 10) 2
Student ID: 100
Students first name: Hello
Student last name: World
Student email: Helloworld#gmail
Student ID: 101
Students first name: john
Student last name: Doe
Student email: johndoe#something
// --- stdout ---
Student ID: 100
Student first name: Hello
Student last name: World
Student email: Helloworld#gmail
Student ID: 101
Student first name: john
Student last name: Doe
Student email: johndoe#something
Enjoy Coding!
Students should be named Student because it only contains information about one student.
You currently declare Students student[10]; locally in each function. Each array is unique and what you enter in one function will not be visible outside the function in which it was declared. You need to pass the information to the functions using it.
Since the user of the program is free to enter any number of students, use a std::vector to store them. A std::vector can grow dynamically.
Instead of having a char[] with a hardcoded lenght for name etc., use std::string. It will, just like std::vector, grow dynamically.
Example:
#include <iostream>
#include <string>
#include <vector>
struct Student {
int studentID;
std::string firstName;
std::string lastName;
std::string email;
};
// a function to print one student
std::ostream& operator<<(std::ostream& os, const Student& s) {
return os
<< "Student ID: " << s.studentID << '\n'
<< "Student first name: " << s.firstName << '\n'
<< "Student last name: " << s.lastName << '\n'
<< "Student email: " << s.email << '\n'
;
}
// return a std::vector<Student>
std::vector<Student> showStudentAddMenu()
{
using std::cin, std::cout;
std::vector<Student> students;
cout << "How many students would you like to add? ";
// check that extraction was successful before using addStudentNumber:
if(size_t addStudentNumber; cin >> addStudentNumber) {
students.reserve(addStudentNumber);
Student s;
for (size_t i=0; i<addStudentNumber; ++i)
{
cout << "Student ID: ";
cin >> s.studentID;
cout << "Students first name: ";
cin >> s.firstName;
cout << "Student last name: ";
cin >> s.lastName;
cout << "Student email: ";
if(cin >> s.email)
students.push_back(s); // store one student
else
break; // if input failed
}
}
return students;
}
void studentLookup(const std::vector<Student>& students)
{
// print all students
for (const Student& s : students)
{
std::cout << s; // using our operator<< that we defined under Student
}
}
int main() {
std::vector<Student> students = showStudentAddMenu();
studentLookup(students);
}
Fields of the struct are not null-terminated, thus they are not valid C-strings and cannot be printed like ones.
For a struct defined this way compiler would know the size of each field, so you can print them with something like:
Student student {...};
std::cout << std::string_view(student.firstName, sizeof(Students::firstName)) << std::endl;

Using a struct to hold information entered by the user C++

Okay, so I am writing a C++ program to declare a struct data type that holds the following information on an employee (First Name, Last Name, ID, Pay Rate, and Hours). My problem is that the user can only enter in the ID and First Name, then the whole program runs without letting the user enter the rest of the data.
Heres my code:
#include <iostream>
#include <iomanip>
using namespace std;
struct Employee
{
int employeeID;
char firstName;
char lastName;
float payRate;
int hours;
};
int main()
{
int i, j;
cout << "How Many Employees Do You Wish To Enter?:\n\n";
cin >> j;
Employee info;
for (i = 0; i < j; i++)
{
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << setw(5) << "\n Please Enter The Employee ID Number: ";
cin >> info.employeeID;
cout << setw(5) << "\n Please Enter Employees First Name: ";
cin >> info.firstName;
cout << setw(5) << "\n Please Enter Employees Last Name: ";
cin >> info.lastName;
cout << setw(5) << "\n Please Enter Employees Pay Rate: ";
cin >> info.payRate;
cout << setw(5) << "\n Please Enter The Hours The Employee Worked:
";
cin >> info.hours;
}
cout << "\n\n \n";
cout << "ID" << setw(15) << "First Name" << setw(10) << "Last Name" <<
setw(10) << "Pay Rate" << setw(10) << "Hours";
cout << endl;
for (i = 0; i < j; i++)
{
cout << "\n" << info.employeeID << setw(15) << info.firstName << setw(10) << info.lastName << setw(10) << info.payRate << setw(10) << info.hours;
}
cout << "\n\n \n";
system("pause");
return 0;
};
#include <iostream>
#include <iomanip>
#include <string> //Allows you to use strings, which are way more handy for text manipulation
#include <vector> //Allows you to use vector which are meant to be rezied dynamicaly, which is your case
using namespace std;
struct Employee
{
int employeeID;
string firstName; //HERE : use string instead of char (string are array of char)
string lastName; //HERE : use string instead of char
float payRate;
int hours;
};
int main()
{
int j;
cout << "How Many Employees Do You Wish To Enter?:\n\n";
cin >> j;
vector<struct Employee> info; //creation of the vector (dynamic array) to store the employee info the user is going to give you
for (int i = 0; i < j; i++) //declare your looping iterator "i" here, you will avoid many error
{
struct Employee employee_i; // create an employee at each iteration to associate the current info
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << "\n Please Enter The Employee ID Number: ";
cin >> employee_i.employeeID;
cout << "\n Please Enter Employees First Name: ";
cin >> employee_i.firstName;
cout << "\n Please Enter Employees Last Name: ";
cin >> employee_i.lastName;
cout << "\n Please Enter Employees Pay Rate: ";
cin >> employee_i.payRate;
cout << "\n Please Enter The Hours The Employee Worked: ";
cin >> employee_i.hours;
info.push_back(employee_i); //store that employee info into your vector. Push_back() methods expands the vector size by 1 each time, to be able to put your item in it
} // because you employee variable was create IN the loop, he will be destruct here, but not the vector which was created outside
cout << "\n\n \n";
for (int i = 0; i < j; i++) //the loop to get back all the info from the vector
{
cout << "ID :" << info[i].employeeID << " First Name :" << info[i].firstName << " Last Name :" <<
info[i].lastName << " Pay Rate :" << info[i].payRate << " Hours :"<< info[i].hours;
cout << endl;
//notice the info[i], which leads you to the employee you need and the ".hours" which leads to the hours info of that specific employee
}
system("pause");
return 0;
}
First, please read Tips and tricks for using C++ I/O (input/output). It might be helpful to understand C++ I/O.
Here are some comments on your code:
First
Use string instead of char.
struct Employee
{
int employeeID;
string firstName;
string lastName;
float payRate;
int hours;
};
Second
Use array of Employee object to store multiple employees.
Employee info[100];
Third
Use cin carefully depending data types. In your case, it would be something like this:
cout << "Enter in the Data for Employee number " << i + 1 << endl;
cout << setw(5) << "\n Please Enter The Employee ID Number: ";
cin >> info[i].employeeID;
cin.ignore(); //It is placed to ignore new line character.
cout << setw(5) << "\n Please Enter Employees First Name: ";
getline (cin, info[i].firstName);
cout << setw(5) << "\n Please Enter Employees Last Name: ";
getline (cin, info[i].lastName);
cout << setw(5) << "\n Please Enter Employees Pay Rate: ";
cin >> info[i].payRate;
cout << setw(5) << "\n Please Enter The Hours The Employee Worked: ";
cin >> info[i].hours;
Fourth
std::getline() can run into problems when used before std::cin >> var. So, std::cin.ignore() can be used in this case to solve the problem.
I hope it helps.

C++: Student Record Program

I am in desperate need of help. I am supposed to create a student record using structs and vectors.
In the program, I should have:
For a given student, identified either by name or student number
(a) Enter a new student into the record. (Assume no courses completed.)
(b) Grade point average
(c) Transcript, i.e. a list of courses taken, including credit value and grade earned
(d) Record a newly completed course
A listing, sorted by name, of all students who have taken a given course.
A listing, sorted by grade point average, of all students and their grade point averages,
who are on probation, i.e. have a grade point average < 2.0 .
This is what I have so far... and I seem to be having troubles with the user input how read it into my structs
using namespace std;
struct courses {
string courseName;
int courseNum;
double credit;
char grade;
};
struct students {
string name;
int id;
vector<courses> c;
};
int main() {
// variables
string name;
char selector;
students s;
courses d;
vector<students> student;
vector<courses> course;
// (1) create a menu: (a) user input, (b) echo record (with overall gpa), (c) failed students
do {
// prompt for user input
cout << "Enter Q to (Q)uit, (C)reate new student record, (S)how all record(s) on file, show students on (P)robation: ";
cin >> selector;
selector = toupper(selector);
switch (selector) {
// (a) ask and get for user input:
// student info first
// courses second
case 'C':
// variables within case C
char answer;
char answerAddAnotherCourseEntry;
char answerToAnotherStudentRecord;
do {
cout << "Enter your name and student ID number: ";
cin >> s.name >> s.id;
student.push_back(s);
do {
cout << "Do you want to create a student course entry ('y' or 'n')? ";
cin >> answer;
answer = toupper(answer);
cout << "Enter your course number, course name, grade received and credit worth: ";
cin >> d.courseNum >> d.courseName >> d.grade >> d.credit;
course.push_back(d);
cout << "Add another student course entry ('y' or 'n'): ";
cin >> answerAddAnotherCourseEntry;
answerAddAnotherCourseEntry = toupper(answerAddAnotherCourseEntry);
} while (answer == 'N');
cout << "Add another student record ('y' or 'n'): " << endl;
cin >> answerToAnotherStudentRecord;
answerAddAnotherCourseEntry = toupper(answerToAnotherStudentRecord);
} while (answerToAnotherStudentRecord == 'N');
break;
// (b) echo record of vectors
// sort by name
case 'S':
if (student.empty()) {
cout << "\nSorry, no records exist in the database.";
}
else
for (int count = 0; count < student.size(); count++) { //For Loop to Display All Records
cout << "Student name: " << student[count].name << "ID Number: " << student[count].id << endl;
count++;
// another for loop i think
for (int i = 0; i < course.size(); i++) {
cout << "Course info: " << " " << course[i].courseNum << " " << course[i].courseName << " " << course[i].credit << " " << course[i].grade << endl;
i++;
}
}
cout << endl;
break;
// (c) separate failed student into another vector
// sort by gpa
case 'P':
break;
} // bracket closing switch
} // bracket closing do while
while (selector != 'q' && selector != 'Q'); // first do while
The issues I see with your input is that you are trying to store the user input directly in a string, here e.g. in the variable name of the struct s:
cout << "Enter your name and student ID number: ";
cin >> s.name >> s.id;
This does not compile. Instead you can store the name in a temporary char array first and then copy it to s.name.
char studentName[128];
cout << "Enter your name and student ID number: ";
cin >> studentName >> s.id;
s.name = studentName;
You can also work with getline() if you want to store your input directly in a string.
Furthermore you try to directly output the variable student[count].name, which is a string, to cout:
cout << "Student name: " << student[count].name << "ID Number: " << student[count].id << endl;
Converting the string to a char array first makes this compile:
cout << "Student name: " << student[count].name.c_str() << "ID Number: " << student[count].id << endl;

Multiple Constructors Class Setters C++

So, I just had a question about my professors feedback on one of the programs we did. I didn't quite understand her feedback on what she meant by putting setters functions in the second constructor. Here is what she said:
Next time be sure to do the Reading and Preparation assigned before you attempt a lab. Read the assignment carefully.
The problem says the overloaded constructor (constructor #2) should call the setter functions.
The overloaded constructor (constructor #2) was not tested. Create an object with the overloaded constructor like so: Inventory itemTwo(666,3,.99);
Nice class, nice main program and coding style.
This was the problem:
Problem
And lastly, here's my code:
#include <iostream>
#include <iomanip>
using namespace std;
class Inventory
{
private:
int itemNumber; //Private Class Members
int quanity;
double cost;
public:
Inventory(); //Public Member Functions
Inventory(int i, int q, double c);
void setItemNumber(int);
void setQuanity(int);
void setCost(double);
int getItemNumber() const;
int getQuanity() const;
double getCost() const;
double getTotalCost() const;
};
int main()
{
int itemNum;
int qty;
double price;
Inventory itemOne; //Declares itemOne and itemTwo being an Inventory class objects
Inventory itemTwo;
/****************************************************************************/
cout << "Please Enter Data For Item One\n"; //Data entry for Item One
cout << "Enter item number: ";
cin >> itemNum;
while (itemNum < 0) //Safegaurds for data
{
cout << "Please enter a non-negative item number: ";
cin >> itemNum;
}
cout << "Enter quanity: ";
cin >> qty;
while (qty < 0)
{
cout << "Please enter a non-negative quanity number: ";
cin >> qty;
}
cout << "Enter price: ";
cin >> price;
while (price < 0)
{
cout << "Please enter a non-negative price: ";
cin >> price;
}
itemOne.setItemNumber(itemNum); //Passes All Data To Correct Functions
itemOne.setQuanity(qty);
itemOne.setCost(price);
cout << endl; //Formatting
/****************************************************************************/
cout << "Please Enter Data For Item Two\n"; //Data Entry for Item Two
cout << "Enter item number: ";
cin >> itemNum;
while (itemNum < 0)
{
cout << "Please enter a non-negative item number: ";
cin >> itemNum;
}
cout << "Enter quanity: ";
cin >> qty;
while (qty < 0)
{
cout << "Please enter a non-negative quanity number: ";
cin >> qty;
}
cout << "Enter price: ";
cin >> price;
while (price < 0)
{
cout << "Please enter a non-negative price: ";
cin >> price;
}
itemTwo.setItemNumber(itemNum); //Passes All Data To Correct Functions
itemTwo.setQuanity(qty);
itemTwo.setCost(price);
cout << endl; //Formatting
/****************************************************************************/
cout << fixed << showpoint << setprecision(2);
//All input displayed here
cout << "Here's the data you entered for item one:\n";
cout << "Item Number: " << " " << itemOne.getItemNumber() << endl;
cout << "Item Quanity: " << " " << itemOne.getQuanity() << endl;
cout << "Item Cost: " << " " << "$" << itemOne.getCost() << endl;
cout << "Item Total Cost: " << " " <<"$" << itemOne.getTotalCost() << endl << endl;
cout << "Here's the data you entered for item two:\n";
cout << "Item Number: " << " " << itemTwo.getItemNumber() << endl;
cout << "Item Quanity: " << " " << itemTwo.getQuanity() << endl;
cout << "Item Cost: " << " " << "$" << itemTwo.getCost() << endl;
cout << "Item Total Cost: " << " " <<"$" << itemTwo.getTotalCost() << endl;
return 0;
}
Inventory::Inventory() //Default Constructor
{
itemNumber = 0;
quanity = 0;
cost = 0;
}
Inventory::Inventory(int i, int q, double c) //Constructor #2
{
itemNumber = i;
quanity = q;
cost = c;
}
void Inventory::setItemNumber(int i) //Re-Evaluates For a Negative Number and
{ //Passes User's Entered Data to the Private class
if (i >= 0)
itemNumber = i;
else
itemNumber = 0;
}
void Inventory::setQuanity(int q) //Re-Evaluates For a Negative Number and
{ //Passes User's Entered Data to the Private class
if (q >= 0)
quanity = q;
else
quanity = 0;
}
void Inventory::setCost(double c) ////Re-Evaluates For a Negative Number and
{ //Passes User's Entered Data to the Private class
if (c >= 0)
cost = c;
else
cost = 0;
}
int Inventory::getItemNumber() const //All 'Getter' Functions to Display Object's Data
{ //Whilst Keeping Data Integrity With 'const'
return itemNumber;
}
int Inventory::getQuanity() const
{
return quanity;
}
double Inventory::getCost() const
{
return cost;
}
double Inventory::getTotalCost() const //Calculates Total Cost and Returns
{
return cost * quanity;
}
/*
-----------------------------------------------------
Please Enter Data For Item One
Enter item number: 1303
Enter quanity: 10
Enter price: 2.50
Please Enter Data For Item Two
Enter item number: 5676
Enter quanity: 54
Enter price: 5.65
Here's the data you entered for item one:
Item Number: 1303
Item Quanity: 10
Item Cost: $2.50
Item Total Cost: $25.00
Here's the data you entered for item two:
Item Number: 5676
Item Quanity: 54
Item Cost: $5.65
Item Total Cost: $305.10
-----------------------------------------------------
Please Enter Data For Item One
Enter item number: 7456
Enter quanity: 10
Enter price: 10.9
Please Enter Data For Item Two
Enter item number: 0293
Enter quanity: 5
Enter price: 109.23
Here's the data you entered for item one:
Item Number: 7456
Item Quanity: 10
Item Cost: $10.90
Item Total Cost: $109.00
Here's the data you entered for item two:
Item Number: 293
Item Quanity: 5
Item Cost: $109.23
Item Total Cost: $546.15
-----------------------------------------------------
*/
Your professor probably meant that you should call the setter functions in the constructor instead of setting the values directly:
Inventory::Inventory(int i, int q, double c) //Constructor #2
{
setItemNumber(i);
setQuantity(q);
setCost(c);
}
She's right. You are taking user input, therefore you must validate it with your setters, you created them for a reason.
Inventory::Inventory(int i, int q, double c) //Constructor #2
{
setItemNumber(i);
setQuantity(q);
setCost(c);
}