I am trying to push a certain struct that exists in my private class into a vector of the class type records. I get the variable data in my main function but for some reason I keep getting an out of bounds error when trying to copy the information into the struct. If you could explain the error in my method of pushing the struct into the class vector that would be great... I included my planned print function as well.
Here's the class :
class students
{
public:
// All necessary member functions here
students(int RUID, string first_name, string last_name, vector<double> quiz_grades, array<double, 3> exam_grades)
{
record records;
records.RUID = RUID;
records.first_name = first_name;
records.last_name = last_name;
for (int i = 0; i < quiz_grades.size(); ++i)
{
records.quiz_grades[i] = quiz_grades[i];
}
for (int i = 0; 0 < 3; ++i)
{
records.exam_grades[i] = exam_grades[i];
}
student_records.push_back(records);
}
void printRecords()
{
//vector<record>::iterator it = student_records.begin(); it != student_records.end(); ++it
for (unsigned int i = 0; i < student_records.size(); ++i)
{
cout << "Ruid: " << student_records[i].RUID << endl;
cout << "First Name: " << student_records[i].first_name << endl;
cout << "Last Name: " << student_records[i].last_name << endl;
for (unsigned int j = 0; j < student_records[i].quiz_grades.size(); ++j)
{
cout << "Quiz grade " << j + 1 << " is: " << student_records[i].quiz_grades[j] << endl;
}
for (int k = 0; k < 3; ++k)
{
cout << "Test grade " << k + 1 << " is: " << student_records[i].exam_grades[k] << endl;
}
}
}
// using the friend function in class
friend void change_name(students stdn); // passing all necessary inputs
private:
struct record
{
int RUID;
string first_name;
string last_name;
vector<double> quiz_grades;
array<double, 3> exam_grades = { 0,0,0 };
};
vector<record> student_records;
};
Here's my main function:
int main()
{
string input;
bool quit = false;
int RUID;
string first;
string last;
double grade = 100;
vector<double> quizG;
array <double, 3> examG = { 0, 0, 0 };
cout << " --'new' to add, 'quit' to end--" << endl;
while (quit != true)
{
cout << "Please enter would you would like to do: ";
cin >> input;
cout << endl;
if (input == "quit")
{
quit = true;
break;
}
if (input == "new")
{
cout << "Please enter the RUID: ";
cin >> RUID;
cout << endl << "Please enter the first name: ";
cin >> first;
cout << endl << "Please enter the last name: ";
cin >> last;
cout << "Enter quiz grades. Enter number less than 0 to stop." << endl;
while (grade >= 0)
{
cout << "Enter quiz grade: ";
cin >> grade;
if (grade >= 0)
{
quizG.push_back(grade);
}
else if (grade < 0)
{
break;
}
}
for (int i = 0; i < 3; ++i)
{
cout << "Please enter " << i + 1 << " test grade: ";
cin >> grade;
examG[i] = grade;
}
}
students stdn(RUID, first, last, quizG, examG);
//stdn.printRecords();
}
// change_name(stdn);
return 0;
In students::students(),
for (int i = 0; 0 < 3; ++i)
// ^^^ should be `i`
is obviously wrong.
Related
I have this program that is barely started:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>
using namespace std;
class Grade
{
public:
string studentID;
int userChoice = 0;
int size = 0;
double* grades = new double[size]{0};
};
void ProgramGreeting(Grade &student);
void ProgramMenu(Grade& student);
string GetID(Grade& student);
int GetChoice(Grade& student);
void GetScores(Grade& student);
int main()
{
Grade student;
ProgramGreeting(student);
ProgramMenu(student);
}
// Specification C1 - Program Greeting function
void ProgramGreeting(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << "Welcome to the GPA Analyzer! " << endl;
cout << "By: Kate Rainey " << endl;
cout << "Assignment Due Date: September 25th, 2022 " << endl;
cout << "--------------------------------------------" << endl;
GetID(student);
cout << "For Student ID # " << student.studentID << endl;
}
void ProgramMenu(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << setw(25) << "Main Menu" << endl;
cout << "1. Add Grade " << endl;
cout << "2. Display All Grades " << endl;
cout << "3. Process All Grades " << endl;
cout << "4. Quit Program." << endl;
cout << "--------------------------------------------" << endl;
GetChoice(student);
}
string GetID(Grade &student)
{
cout << "Enter the student's ID: ";
cin >> student.studentID;
if (student.studentID.length() != 8) {
cout << "Student ID's contain 8 characters ";
GetID(student);
}
return student.studentID;
}
int GetChoice(Grade &student)
{
cout << "Enter your selection: ";
cin >> student.userChoice;
if (student.userChoice == 1) {
GetScores(student);
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 4)
{
exit(0);
}
else
{
cout << "Please enter 1, 2, 3 or 4" << endl;
GetChoice(student);
}
}
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
for (int i = 0; i < student.size; i++) {
student.grades[i] = score;
}
count++;
}
for (int i = 0; i < student.size; i++) {
cout << student.grades[i] << " ";
}
}
I am trying to make sure my array is recording all test scores, but when I output the array in my GetScore function, each element in the array is the same or equal to the last score I entered. For example, if I choose 3 for size and then enter three values of 99.2 86.4 90.1, all three elements will read 90.1.
Why is this happening?
Your Grade class is allocating an array of 0 double elements (which is undefined behavior), and then your GetScores() function does not reallocate that array after asking the user how many scores they will enter, so you are writing the input values to invalid memory (which is also undefined behavior).
Even if you were managing the array's memory correctly (ie, by using std::vector instead of new[]), GetScores() is also running a for loop that writes the user's latest input value into every element of the array, instead of just writing it to the next available element. That is why your final output displays only the last value entered in every element. You need to get rid of that for loop completely.
Try something more like this instead (there are several other problems with your code, but I'll leave those as separate exercises for you to figure out):
class Grade
{
public:
...
int size = 0;
double* grades = nullptr;
};
...
void GetScores(Grade &student)
{
int size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
if (student.size != size) {
delete[] student.grades;
student.grades = new double[size]{0};
student.size = size;
}
for(int i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
for (int i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
Alternatively:
#include <vector>
...
class Grade
{
public:
...
vector<double> grades;
};
...
void GetScores(Grade &student)
{
size_t size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
student.grades.resize(size);
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
/* alternatively:
student.grades.clear();
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades.push_back(score);
}
*/
for (size_t i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
I removed my for loop from my while loop.
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
student.grades[count] = score;
count++;
}
for (int j = 0; j < student.size; j++) {
cout << student.grades[j] << " ";
}
}
Good day, I'm having difficulty on the last two parts of my program where it's supposed to only output players who got maximum/minimum scores, I need help on how to do it because I'm really confused. If it's also alright to provide some explanations I'd really appreciate it.
I tried this approach:
#include <iostream>
using namespace std;
int main() {
double lrgst, lrgst2, lrgst3;
int numbers[5];
lrgst = lrgst2 = lrgst3;
for (int i = 0; i < 5; i++) {
cin >> numbers[i];
}
for (int i = 0; i < 5; i++) {
if (numbers[i] > lrgst) {
lrgst3 = lrgst2;
lrgst2 = lrgst;
lrgst = numbers[i];
} else if (numbers[i] > lrgst2) {
lrgst3 = lrgst2;
lrgst2 = numbers[i];
} else if (numbers[i] > lrgst3) {
lrgst3 = numbers[i];
}
}
cout << "largest are: " << lrgst << " " << lrgst2 << " " << lrgst3;
}
this is my actual code:
#include <iostream>
using namespace std;
struct playerdata {
char name[50];
int age, score1, score2;
double average;
};
int main() {
int choice, i = 1, j = 1, z = 1, backtomain2;
char backtomain;
playerdata p1[10];
do {
for (int a = 0; a < 47; a++) {
cout << "=";
}
cout << "\n";
for (int b = 0; b < 22; b++) {
cout << " ";
if (b == 21) {
cout << "MENU \n";
}
}
for (int c = 0; c < 47; c++) {
ocut << "=";
}
cout << " "
"\n1. Add record\n"
"2. View players records\n"
"3. Compute for the average\n"
"4. Show the player(s) who gets the max average.\n"
"5. Show the player(s) who gets the min average.\n"
"6. Exit\n"
"Enter your choice:";
cin >> choice;
if (choice == 1) {
cout << "Add player data" << endl;
do {
cout << "Enter player " << i << " nickname:";
cin >> p1[i].name;
cout << "Enter player " << i << " age:";
cin >> p1[i].age;
cout << "Enter player " << i << " score 1:";
cin >> p1[i].score1;
cout << "Enter player " << i << " score 2:";
cin >> p1[i].score2;
cout << "Enter again? (Y/N)";
cin >> backtomain;
i++;
}
while (backtomain != 'N' && backtomain != 'n' && i < 7);
if (choice == 2) {
cout << "Player records" << endl;
cout << "Player nickname "
<< "Player age "
<< " player score 1"
<< "
player score 2\n ";
for (z = 1; z <= i - 1; z++) {
cout << p1[z].name << " " << p1[z].age << "" << p1[z].score1 << ""
<< p1[z].score2 << "\n";
}
cout << "Press 1 to go back to main menu\n";
cin >> backtomain;
}
if (choice == 3) {
cout << "Computing for average...\n";
for (int d = 1; d <= i - 1; d++) {
p1[d].average = (p1[d].score1 + p1[d].score2) / 2.0;
cout << "\n" << p1[d].average << "\n";
}
cout << "Press 1 to go back to main menu\n";
cin >> backtomain;
}
if (choice == 4) {
cout << "Player(s) who got the max average:\n";
cout << "\nPress 1 to go back to main menu";
cin >> backtomain;
}
if (choice == 5) {
cout << "player(s) who got the min average: \n";
cout << "Press 1 to go back to main menu";
cin >> backtomain;
}
}
while (choice != 6);
}
You can simply sort the array of players for that
int n = sizeof(p1)/ sizeof(p1[0]);
sort(p1, p1+n, compPlayer);
//larget at pl[0]
//smallest at pl[9]
where
bool compPlayer(playerdata p1, playerdata p2) {
return (p1.score1+p1.score2) > (p2.score1+p2.score2);
//use score incase average has not been calculated for all players yet
}
I have to calculate the total of scores the participants received from the judges. And the one who gets the highest score will be the winner. I have to display the name of the winner but it displays the wrong winner. how do I solve this?
int main(){
int scores[5][2], i, j; int sum =0;
string name [5];
for(int i=0;i<5;i++)
{
cout << "Enter participant's name: \n";
cin >> name[i];
cout<<"Enter scores for " << name[i] <<endl;
for(j=0;j<2;j++)
{
cin >> scores[i][j];
}
}
for(int i=0; i<5; i++)
{
sum = 0;
for(j=0; j<2; j++)
{
sum += scores[i][j];
}
cout<<"Total scores of " << name[i] << " " <<" is "<<sum<<endl;
}
int max, min, count;
int index[5];
max = min, count=0;
index[5]={0};
for(int i=0; i<5; i++)
{
for(j=0; j<2; j++)
{
if (scores[i][j]>max)
{
max=scores[i][j];
}
}
for(int i=0; i<5; i++)
{
if(scores[i][j]==max)
{
index[count]=scores[i][j];
count++;
}
}
if (count==1)
cout<<"The winner is " << index[count-1] << name[i] << endl;
}
return 0;
}
You could use a running maxima algorithm without having to store all entries.
int main()
{
std::string name;
int max_score = -1;
std::string owner_max_score;
cout << "Enter participant's name: \n";
while (std::getline(cin, name))
{
int score1, score2;
cout<<"Enter 2 scores for " << name <<endl;
cin >> score1 >> score2;
if (score1 > max_score)
{
max_score = score1;
owner_max_score = name;
}
if (score2 > max_score)
{
max_score = score2;
owner_max_score = name;
}
cout << "\nEnter participant's name: \n";
}
cout << owner_max_score << " has highest score of " << max_score << endl;
return 0;
}
To stop the loop, terminate the input. Some platforms use Ctrl-D, some use Ctrl-Z or Ctrl-C.
You could also use a std::vector of structs:
struct Student
{
std::string name;
int score1;
int score2;
void console_input()
{
std::cout << "\n"
<< "Enter student's name:\n";
std::getline(std::cout, name);
std::cout << "\n"
<< "Enter 2 scores for "
<< name
<< "\n";
std::cin >> score1 >> score2;
}
int max_score() const
{
return std::max(score1, score2);
}
};
int main()
{
Student s;
std::vector<Student> student_scores;
std::cout << "Enter quantity of students: ";
std::cint >> student_quantity;
for (int i = 0; i < student_quantity; ++i)
{
s.console_input();
student_scores.push_back(s);
}
std::string owner_max_score = student_scores[0].name;
std::int highest_score = student_scores[0].max_score();
for (int i = 1; i < student_quantity; ++i)
{
const int student_max_score = student_scores[i].max_score();
if (student_max_score > highest_score)
{
highest_score = student_max_score;
owner_max_score = student_scores[i].name;
}
}
std::cout << "\n\n"
<< owner_max_score
<< " has highest score: "
<< highest_score
<< "\n";
return 0;
}
I am creating an employee structure, with an array. However, it keeps returning this error.
The program is supposed to allow the user to enter an id number and validate, which already works. Then it is supposed to allow the user to search for a value inside the array.
#include <iostream>
#include <string.h>
using namespace std;
struct Employee
{
int idNum;
double payRate;
string firstName, lastName;
};
int main()
{
int error;
const int SIZE = 5;
Employee employee[SIZE];
for(int k = 0; k < SIZE; ++k)
{
employee[k].idNum = 0;
employee[k].payRate = 0;
}
for(int count = 0; count < SIZE; ++count)
{
error = 0;
cout << "Enter the employee's id number " << endl;
int tempId;
cin >> tempId;
for (int i = 0; i < SIZE; ++i)
{
if (employee[i].idNum == tempId)
error = 1;
}
while(error == 1)
{
cout << "Invalid entry. Please enter a new id number " << endl;
cin >> employee[count].idNum;
for(int i = 0; i < count; ++i)
{
error = 0;
if(employee[i].idNum == employee[count].idNum)
error = 1;
}
}
cout << "Enter the employee's pay rate " << endl;
cin >> employee[count].payRate;
cout << "Enter the employee's first name " << endl;
cin >> employee[count].firstName;
cout << "Enter the employee's last name " << endl;
cin >> employee[count].lastName;
}
int choice;
cout << "Enter 1 to search for an employee by id number, enter 2 to search by last name, and enter 3 to search by pay " << endl;
cin >> choice;
if(choice == 1)
{
int idNumC;
cout << "Enter an id number ";
cin >> idNumC;
for(int count = 0; count < SIZE; ++count)
{
if(employee[count].idNum == idNumC)
cout << employee[count].idNum;
}
}
if(choice == 2)
{
string name;
cout << "Enter the employee's last name " << endl;
cin >> name;
for(int count = 0; count < SIZE; ++count)
{
if(strcmp(employee[count].lastName, name) == 0)
cout << "ID number: "<< employee[count].idNum << " First name: " << employee[count].firstName << " Last Name: " << employee[count].lastName << " Hourly Pay: " << endl;
}
}
if(choice == 3)
{
int nam;
cout << "Enter the employee's pay rate " << endl;
cin >> nam;
for(int count = 0; count < SIZE; ++count)
{
if(employee[count].payRate == nam)
cout << "ID number: "<< employee[count].idNum << " First name: " << employee[count].firstName << " Last Name: " << employee[count].lastName << " Hourly Pay: " << endl;
}
}
}
I get
76:41: error: cannot convert 'std::string {aka
std::basic_string<char>}' to 'const char*' for argument '1' to 'int
strcmp(const char*, const char*)'
How can I fix this error? Thank you for your time.
You can compare two string with == so i should you if(employee[count].lastName==name) instead of if(strcmp(employee[count].lastName, name) == 0)
But if you want use strcmp try
if(strcmp(employee[count].lastName.c_str(), name.c_str()) == 0)
This program is supposed to accept values from the keyboard, and require that the user re-enter the value for the employee's id number. However it keeps outputting "Invalid variable" even if I enter a correct value. It needs to only output that if the value is already been entered. For example
if I enter "3453" as the id number it will still output "Invalid Variable" even if I have not entered that number before.
#include <iostream>
using namespace std;
struct Employee
{
int idNum;
double payRate;
char firstName, lastName;
};
int main()
{
int error;
const int SIZE = 5;
Employee employee[SIZE];
for (int k = 0; k < SIZE; ++k)
{
employee[k].idNum = 0;
employee[k].payRate = 0;
}
for (int count = 0; count < SIZE; ++count)
{
error = 0;
cout << "Enter the employee's id number " << endl;
cin >> employee[count].idNum;
for (int i = 0; i < SIZE; ++i)
{
if (employee[i].idNum == employee[count].idNum)
error = 1;
}
while (error == 1)
{
cout << "Invalid entry. Please enter a new id number " << endl;
cin >> employee[count].idNum;
for (int i = 0; i < SIZE; ++i)
{
error = 0;
if (employee[i].idNum == employee[count].idNum)
error = 1;
}
}
cout << "Enter the employee's pay rate " << endl;
cin >> employee[count].payRate;
cout << "Enter the employee's first name " << endl;
cin >> employee[count].firstName;
cout << "Enter the employee's last name " << endl;
cin >> employee[count].lastName;
int choice;
cout << "Enter 1 to search for an employee by id number, enter 2 to search by last name, and enter 3 to search by pay "
<< endl;
cin >> choice;
}
int choice;
cout << "Enter 1 to search for an employee by id number, enter 2 to search by last name, and enter 3 to search by pay "
<< endl;
cin >> choice;
if (choice == 1)
{
int idNumC;
cout << "Enter an id number ";
cin >> idNumC;
for (int count = 0; count < SIZE; ++count)
{
if (employee[count].idNum == idNumC)
cout << employee[count].idNum;
}
}
if (choice == 2)
{
char name;
cout << "Enter the employee's last name " << endl;
cin >> name;
for (int count = 0; count < SIZE; ++count)
{
if (employee[count].lastName == name)
cout << "ID number: " << employee[count].idNum
<< " First name: " << employee[count].firstName
<< " Last Name: " << employee[count].lastName
<< " Hourly Pay: " << endl;
}
}
if (choice == 3)
{
int name;
cout << "Enter the employee's last name " << endl;
cin >> name;
for (int count = 0; count < SIZE; ++count)
{
if (employee[count].payRate == name)
cout << "ID number: " << employee[count].idNum
<< " First name: " << employee[count].firstName
<< " Last Name: " << employee[count].lastName
<< " Hourly Pay: " << endl;
}
}
}
My program also will not accept a value of more than one letter into the name. If I try and enter that into the program, the program keeps printing "Invalid entry" until I hit ctrl+c.
for (int i = 0; i < SIZE; ++i)
This checks every element in the array, including the one you have just read. You probably meant to put
for (int i = 0; i < count; ++i)
which will check every element up to (but not including) the one you have just read.
in
for (int i = 0; i < SIZE; ++i)
{
if (employee[i].idNum == employee[count].idNum)
error = 1;
}
employee[count] is one of the employee[i] you're going to compare against which means at some point you will
if (employee[count].idNum == employee[count].idNum)
Which is guaranteed to be true.
But if instead you
int tempId;
cin >> tempId;
for (int i = 0; i < SIZE; ++i)
{
if (employee[i].idNum == tempId)
error = 1;
}
and then set
employee[count].idNum = tempId;
at some later time, you can avoid this problem.
Addendum: I recommend picking this logic up and placing it in its own function. That way A) you don't have to repeat it inside the loop a few lines down where you're repeating the check for each retry and it gets the logic out of the way of the rest of the code. B) you can use the same function later for any other "Does this employee exist?" checks you need to write in the future.
In general You want to have lots of simple, easily-tested functions over one monolithic jack-of-all-trades.