1

I have a weird problem with C++ map.

Firstly I insert filenames as key and an increasing integer as value:

int getdir (const char* dir, map<const char*, int> &filemap)
{
    DIR *dp;

    struct dirent *dirp;
    if((dp  = opendir(dir)) == NULL) 
    {
        cout << "Error(" << errno << ") opening " << dir << endl;
        return errno;
    }
    int index = 0;
    while ((dirp = readdir(dp)) != NULL) 
    {
        string temp1(dir);
        string temp2(dirp->d_name);

        if(!isalpha(temp2[0]))
        {
            continue;
        }

        filemap[dirp->d_name] = index; 
        index++;
    }

    closedir(dp);
    return 0;
}

Then in another function, I tried to look up this map to find if a certain filename exists by the following code snippet:

stringstream ss(firststr);
string sourceid;
getline(ss, sourceid, ':');
sourceid = sourceid+".txt";

if(filemap.find(sourceid.c_str())!=filemap.end())
{
   cout<<"found"<<endl;
}

I've checked sourceid.c_str() is identical to a certain key in filemap, but it won't be found in the map.

Instead, if I changed the way of inserting element into map to the following (the rest are the same):

...
string temp1(dir);
string temp2(dirp->d_name);

...

filemap[temp2.c_str()] = index;  //previously is filemap[dirp->d_name] = index;
index++;

Then the a certain key can be found in the map in the other function. However the problem is the filemap only contains the last element and its size is 1. It seems that the map's key is being overwritten so that at the end the map contains "last_element => last_index".

I've debugged this for a long time but still cannot solve it. Any help is appreciated.

Iam619
  • 795
  • 2
  • 12
  • 28

1 Answers1

2

In order to use const char* as keys into a map, you need to provide a comparator. See Using char* as a key in std::map

An easier option is to change the map to use std::string as its keys.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • yes..it worked...but why cannot use const char*? I'm happy that it is solved so quickly and sad I've spent such a long time without trying to change it to string...Thank you so much. – Iam619 Nov 24 '12 at 21:52
  • In a nutshell, you need to supply a comparator to make `std::map` work as expected. Without a comparator, `map.find()` will compare the pointers instead of comparing the actual strings. See the answers to http://stackoverflow.com/questions/4157687/using-char-as-a-key-in-stdmap – NPE Nov 24 '12 at 21:56