Jump to content
  • Advertisement
Sign in to follow this  
@root

vector iteration (and hi)

This topic is 4428 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well hi there! I've been lurking around here for some time, learning all kinds of stuff, but now that I have a rather specific problem myself, I figured I might as well register and make my first post. I'll save you the long introduction and will get on with the problem. I'm reading "Beginning C++ Game Programming"(which I'd recommend to my fellow newbies btw) and have finished one of the assignments. It's basically a really simple database for game titles, in which the user has the ability to view the list of games, add to it and remove from it. The chapter itself is about STL. In the assignment I was more or less told to use vectors and iterators. Here is what I came up with:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
	vector<string> list;
	list.push_back("Tetris");
	vector<string>::iterator myIterator;
	vector<string>::const_iterator iter;
	
	string choice;

	cout << "Hello. This is your personal gamelist.\nTo view the list, type 'view'. To add a title to the list, type 'add'\n"
		 <<	"and to remove a title, type 'remove'. To quit the program, type 'quit'.\n";

	do
	{
		cout << "\nview, add, remove or quit?\nYour choice: ";
		cin >> choice;
		
		if (choice == "view")
		{
			for(iter = list.begin(); iter !=list.end(); ++iter)
				cout << endl << *iter;
				cout << endl;
		}
		if (choice == "add")
		{
			string title;
			cout << "\nWhat is the title of the game? ";
			cin >> title;
			list.push_back(title);
			sort(list.begin(), list.end());
		}
		if (choice == "remove")
		{
			string title;
			cout << "\nWhich title do you want remove? ";
			cin >> title;
			for(myIterator = list.begin(); myIterator != list.end(); ++myIterator)
			{
				if(*myIterator == title)
				{
					list.erase(myIterator);
					break;
				}
			}
		}
	}while (choice != "quit");

	cout << "\nThanks for using this program.\n";

	return 0;
}

The problem I'm having lies in the if-statement that handles the removal of a title. As you can see I exit the for-loop by using a break statement. Otherwise myIterator would adress a random piece of memory ("one" after the vector). Now, I tried to outsmart myIterator by repacing "break;" with "--myIterator", but that didn't work. So, I'm not satisfied with the "break". It is a flawed design, as I see it. As long as the user removes one title per time, all is well. But what if I want to let them remove more titles in one go? I know this isn't a huge problem, but I also know this is all basic stuff and I don't wanna miss out on the basic stuff ;) Any help would be greatly appreciated, ofcourse. Also if you feel the urge to comment on any other part of the program, you're welcome to do so.

Share this post


Link to post
Share on other sites
Advertisement
Consider instead using the remove-erase idiom. ex:
list.erase( remove(list.begin(), list.end(), title), list.end());

If you feel a compelling need to do the loop yourself, erase() returns an iterator to one after the element erased. So in your if statement you set the iterator to the return value of erase() and in the else part move the iterator increment. In this case you would remove the iterator increment from the for loop expression.

And for the record: naming a vector list makes my head hurt.

Share this post


Link to post
Share on other sites
erase() returns an iterator that designates the first element beyond the element(s) removed(or end() if there is none left). Of course, in that case you shouldn't incremenent the iterator yourself. So it becomes:


for(myIterator = list.begin(); myIterator != list.end();)
{
if(*myIterator == title)
{
myIterator=list.erase(myIterator);
}
else ++myIterator;

}





-EDIT: Oops, too late...

Share this post


Link to post
Share on other sites
vector::erase() returns the next iterator.

That said, are you trying to remove all of the books that have a certain name, or just the first one?

If the former, then you should probably look into remove(), coupled with erase(). If the latter, then just breaking is fine, since you are done with processing anyway.

Do note that calling your vector "list" could cause problems down the road, since there is a list class.

remove() looks like this, by the way:
#include <algorithm>
// ...
list.erase( remove( list.begin(), list.end(), title ), list.end() );
[edit: And SiCrane takes the cake. ]


jfl.

Share this post


Link to post
Share on other sites
Wow! Three replies, giving me two ways of taking care of the problem, in a matter of minutes. That is just great.

The replies are crystal clear, so no need for more questions. Thanks guys.

About the list, hihi, I never really noticed it myself. I guess ignorance is bliss, right? :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!