0

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?

6
  • 1
    Try *it == userinput instead of it == userinput, if GradeBook has bool operator==(int) const or something that make testing equality of GradeBook and int possible via == operator. Commented Mar 4, 2016 at 2:56
  • 1
    The position of cout << "ID # not found" << endl; may be wrong. Commented Mar 4, 2016 at 2:58
  • Since you've tried vec.erase(vec.begin()+2);, what prevents you from replacing the 2 with a user-provided index? Commented Mar 4, 2016 at 3:01
  • change 'if ( it == userinput )' to something like 'if ( it->ID == userinput )' Commented Mar 4, 2016 at 3:02
  • Using the arrow operator worked! But the code is still having a problem. I updated my question! Commented Mar 4, 2016 at 4:07

3 Answers 3

2

I guess you want to get it done as follows:

  1. If there are any IDs that you've entered, remove all of them and don't print out any message.
  2. If no ID is found, print out an error message.

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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()); 

1 Comment

add an erase and you have the common idiom (note: the answer's current code std::remove(vec.begin(), vec.end(), userinput) does not erase, it only moves items about).
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.