Reputation: 249
I have a class named GradeBook and I already have the objects defined in the class that contained student ID, name and grade. This part of my code works correctly and it stores the objects into the vector and prints properly. I've been trying for hours and cannot figure out or find how to take a user input integer, find if it matches the student ID in the vector and remove the corresponding row.
My Code:
int main(){
...
int userinput;
vector <GradeBook> vec; //named vector "vec"
GradeBook gradeBook1(1, "Bob", 72.3); //created an object in GradeBook
vec.push_back(gradeBook1); //object contains ID#, name, grade
GradeBook gradeBook2(4, "Jim", 85.4);
vec.push_back(gradeBook2);
GradeBook gradeBook3(2, "Rob", 99.6);
vec.push_back(gradeBook3);
GradeBook gradeBook4(3, "Ron", 89.7);
vec.push_back(gradeBook4);
GradeBook gradeBook5(5, "Jon", 66.9);
vec.push_back(gradeBook5);
cout << "Enter the ID# of student you want to remove: ";
cin >> userinput;
vector <GradeBook>::iterator it; //this is where i'm having trouble
for (it = vec.begin(); it != vec.end(); it++) {
if ( it == userinput ){ //I get a bunch of errors here
//i'm not sure how to equate the user input to the iterator
vec.erase(vec.begin()+userinput);
else
{
cout << "ID # not found" << endl;
}
}
....
return 0;
}
UPDATE
Thank you for all of your comments, I took all of them into consideration and ended up fixing my code. Now, it reads the user input ID# and finds the object that contains it. However, it still doesn't work properly.
Here is my new code:
cout << "enter ID to remove" << endl;
cin >> userinput;
vector <GradeBook>::iterator it3;
for (it3 = vec.begin(); it3 != vec.end(); ++it3) {
if ( it3->studentID == userinput ){
vec.erase(vec.begin()+userinput)
}
else
{
cout << "ID # not found" << endl;
}
}
I entered the ID# 3 to be removed as a test. This loops until it correctly finds the object that has the ID number I enter but this is the output it gives:
ID# not found
ID# not found
ID# not found
ID# not found
It stops there because in my program, 3 is the 4th ID number on the list. Can anyone see what's wrong with my code? Why is it doing that?
Upvotes: 0
Views: 8590
Reputation: 46
I guess you want to get it done as follows:
The code implementing these requirements is as follows:
cout << "enter ID to remove" << endl;
cin >> userinput;
bool isFound = false;
vector <GradeBook>::iterator it3;
for (it3 = vec.begin(); it3 != vec.end(); ++it3) {
if (it3->studentID == userinput) {
it3 = vec.erase(it3); // After erasing, it3 is now pointing the next location.
--it3; // Go to the prev location because of ++it3 in the end of for loop.
isFound = true;
}
}
if (!isFound) {
cout << "ID # not found" << endl;
}
After vector::erase remove the element, the iterator passed to the function is invalidated. So you should get a new iterator vector::erase returns. For more details, Check out: vector::remove, std::vector iterator invalidation.
This code works, but I recommend using std::remove and std::remove_if as mentioned before because they make code easier to read and maintenance. (See --it3; line.) In addition, they may run faster.
Upvotes: 2
Reputation: 114
Right now, you're comparing the data location of the iterator to the user input. Where you have written
if ( it == userinput )
try writing
if ( it->ID == userinput )
assuming that your id field is named ID
.
Upvotes: 0
Reputation: 206567
You can use std::remove
or std::remove_if
.
vec.erase(std::remove(vec.begin(), vec.end(), userinput), vec.end());
If the items to be removed need to satisfy some other criteria, you can use std::remove_if
.
vec.erase(std::remove_if(vec.begin(), vec.end(), [](auto item) { ... }), vec.end());
Upvotes: 0