Search code examples
c++stlhashdictionaryplatform-specific

C++ STL Map - find(pair<string,bool>) works in windows Visual Studio but not with g++ in Linux!


I seem to be having issues with using find() with the STL map on different platforms. Here is my code to be complete:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <map>

using namespace std;

void constructDictionary(map<string,bool> &dict);
bool isInDictionary(string word, map<string,bool> &dict);

int main(void)
{

    map<string, bool> dictionary;
    constructDictionary(dictionary);
    map<string, bool>::iterator it = dictionary.begin();

    while(it != dictionary.end()){
        cout << it->first <<endl;
        it++;
    }

    string word;
    while(true){
        cout << "Enter a word to look up: " << endl;
        cin >> word;
        if(isInDictionary(word, dictionary))
            cout << word << " exists in the dictionary." << endl;
        else
            cout << word << " cannot be found in the dictionary." << endl;
    }

    return 0;
}

void constructDictionary(map<string,bool> &dict)
{
    ifstream wordListFile;
    wordListFile.open("dictionaryList.txt");
    string line;

    while(!wordListFile.eof()){
        getline(wordListFile, line);
        dict.insert(pair<string,bool>(line, true));
    }

    wordListFile.close();
}

bool isInDictionary(string word, map<string,bool> &dict)
{
    if(dict.find(word) != dict.end())
        return true;
    else
        return false;
}

isInDictionary() works fine if compiled using visual studio in windows, however, on ubuntu and g++, this only works for the last entry made into the map. Any other word that I query returns false. I don't understand the discrepancy in this behavior. In both cases, the while statement at the beginning of main correctly prints out everything in the map to prove that everything's there.

Any ideas? Thank you.


Solution

  • Is the error in getline and line-endings in your input file? You might find on Linux it is adding an extra \r to each word.

    Assuming none of your words contain spaces, you can get around this by simply using:

    std::string word;
    while( wordListFile >> word )
    {
       if( !word.empty() )
       {
           // do the insert
       }
    }
    

    You can also use getline but "trim" the strings at either end. There is unfortunately no standard trim function. There are a few implementations around.

    You should probably use std::set as your collection type instead of this extra "bool" which is always true whenever there is an entry.