Problem with for and std::map.

Hello,
I am kind of new in c++ and I am trying to make use of a map.
pointer_count is the name of my map.
A sample of my code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

for (Map_Type::iterator iter = pointer_count.begin(); iter != pointer_count.end(); ++iter)
			{
				p_str = iter->first;
				str = *p_str;
				if (data.compare(str) == 0)
				{
					a_Data = iter->first;
					++iter->second;
				}
				else
				{
					pointer_count.insert(std::pair<std::string*, int>(a_Data, 1));
				}
			}



My problem is that I want to compare all the map elements with a_data and if they don't exist in the map, then I should insert a_data in the map. But instead the way I have it, it inserts a_Data after every comparison. I tried to add an if (iter == pointer_count.end()) before the insert() but it didn't work.
Last edited on
std::map has a built-in method, count, which accepts whatever type the key value for the map is. In your case, string*. Using this method you can check whether an element in map already exists with a specific key. Here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <map>

using namespace std;

int main()
{
	map<int, string> Test;
	Test[1] = "Hello";
	Test[3] = "What's up";

	for (unsigned i=0;i < 4;i++)
	{
		cout << "Number of elements that exist with key " << i << ": " << Test.count(i) << endl;
		if (Test.count(i) > 0)
			cout << "\tContents of element with key " << i << ": " << Test[i].c_str() << endl;
	}
	getchar();
	return 0;
}


You should be able to accomplish the same task much more simply using this method, with no real need to iterate through the entire map to check if something is already there.
Last edited on
As the above post illustrates, your code would be a lot simpler if instead of pointers to std::string you'd store the std::string's themselves in the map.

Also, if data is an std::string, you still have operator== available to you, so you needn't use string::compare().

Anyway, you have a logic problem: you insert a_Data for every time you don't find data.
You want to insert a_Data only after you search all the map and never find it once.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (Map_Type::iterator it = pointer_count.begin(); it != pointer_count.end(); ++it)
{
    if (data == *(it->first)) // use less variables, less names to remember
    {
        a_Data = it->first;
        ++it->second;
        break; // get out of the for loop
    }

    if (it+1 == pointer_count.end()) // we reached the end of the map without finding data
    {
        pointer_count[a_Data] = 1; // using map::operator[]
        break;
    }
}


This is a quick and nasty solution for a nasty design, if I may say so.
If I were you, I'd try to simplify the overall design.

http://cplusplus.com/reference/string/operators/
http://cplusplus.com/reference/stl/map/operator%5B%5D/

Edit: Code mistake.
Last edited on
@Catfish I like this approach but it seems that I cannot increase "it" like this..
I am getting this "error: no match for ‘operator+’ in ‘it + 1’"
Last edited on
My mistake, sorry. Disclaimer: I didn't test the code.

I guess you could do
1
2
3
4
5
6
if (++it == pointer_count.end())
{
    // --it; // doesn't matter anyway, we're leaving the loop
    pointer_count[a_Data] = 1;
    break;
}

I did it another way, but thank you very much.
Topic archived. No new replies allowed.