Programming Tips - How can I make a STL map with a case insensitive string for key?

Date: 2007nov27 Language: C/C++ Q. How can I make a STL map with a case insensitive string for key? A. There are several ways. 1. Convert the key to lowercase before using. 2. You can make your own std::string-like class where the compares are not case sensitive. 3. You can use traits to make std::string case insensitive. 4. You can supply a 3rd parameter for comparing to the <map> template as we show here... from http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=2902
// disable warnings about long names #ifdef WIN32 #pragma warning( disable : 4786) #endif #include <string> #include <map> #include <iostream> using namespace std; // case-independent (ci) string less_than // returns true if s1 < s2 struct ci_less : binary_function<string, string, bool> { // case-independent (ci) compare_less binary function struct nocase_compare : public binary_function<unsigned char,unsigned char,bool> { bool operator() (const unsigned char& c1, const unsigned char& c2) const { return tolower (c1) < tolower (c2); } }; bool operator() (const string & s1, const string & s2) const { return lexicographical_compare (s1.begin (), s1.end (), // source range s2.begin (), s2.end (), // dest range nocase_compare ()); // comparison } }; // end of ci_less // OR a simpler (and probably faster) version (by dave): struct ci_less { bool operator() (const string & s1, const string & s2) const { return stricmp(s1.c_str(), s2.c_str()) < 0; } }; typedef map<string, int, ci_less> age_map; int main() { // make a map of people age_map people; // add items to list people ["Nick"] = 28; people ["John"] = 14; people ["Mary"] = 88; // find someone by key cout << "Finding person 'nick' ..." << endl; age_map::const_iterator i = people.find ("nick"); if (i == people.end ()) cout << "Not found." << endl; else cout << "Found age = " << i->second << endl; return 0; } // end of main
Output
Finding person 'nick' ... Found age = 28