stricmp(string.c_str(),"somestring");
std::string case insensitive comparison
Apparently using operator== does a case-sensitive compare.
I was wondering if there was an easier way than doing:
std::string temp = "SomeThIng";std::transform( temp.begin(), temp.end(), temp.begin(), temp.end(), tolower );if( temp == str ) // yadda
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!
There are ways, but you will get into trouble with locales anyways (i.e. what is the meaning of ''case'')
You can use lexicographical_compare and give it your own comparison operator.
Or, for better efficiency, define your comparison as a functor
Assuming tolower() is inlined too, that should go well.
[Questions (STFW) | GDNet Start Here | GDNet Search | Forum FAQ | Google | Asking Smart Questions ]
[Docs (RTFM) | MSDN | SGI''s STL | OpenGL | File formats]
[C++ Must Haves (RTFS) | MinGW | Boost | Loki | FLTK | SDL ]
Stolen from Magmai Kai Holmlor, who held it from Oluseyi, who was inspired by Kylotan...
You can use lexicographical_compare and give it your own comparison operator.
#include <algorithm>using std::lexicographical_compare;bool CaseInsensitiveLess( const char& c1, const char& c2 ){ return tolower(c1)<tolower(c2);}lexicographical_compare( str1.begin(), str1.end(), str2.begin(), str2.end(), CaseInsensitiveLess );
Or, for better efficiency, define your comparison as a functor
struct CaseInsensitiveLess{ inline bool operator()( const char& c1, const char& c2 ) const { return tolower(c1)<tolower(c2); }};lexicographical_compare( str1.begin(), str1.end(), str2.begin(), str2.end(), CaseInsensitiveLess() );// note the presence of parentheses, we are creating a temporary object by calling the constructor for CaseInsensitiveLess
Assuming tolower() is inlined too, that should go well.
[Questions (STFW) | GDNet Start Here | GDNet Search | Forum FAQ | Google | Asking Smart Questions ]
[Docs (RTFM) | MSDN | SGI''s STL | OpenGL | File formats]
[C++ Must Haves (RTFS) | MinGW | Boost | Loki | FLTK | SDL ]
Stolen from Magmai Kai Holmlor, who held it from Oluseyi, who was inspired by Kylotan...
The last post has it exactly right .. EXCEPT ...i don''t understand why you say ... to make it more efficient ... use a function ...
I assume you are saying that, because you know how to inline a member function .. but you can inline ANY function ... that is the point. An inline functor member will be less efficient than a normal function ... because it is not static ... and therefore might pass a "this" pointer to the function (compiler optimization not considered), even though there is no member data to care about.
So write a normal inline function ... and pass it to lexigraphicalcompare
Good Luck
I assume you are saying that, because you know how to inline a member function .. but you can inline ANY function ... that is the point. An inline functor member will be less efficient than a normal function ... because it is not static ... and therefore might pass a "this" pointer to the function (compiler optimization not considered), even though there is no member data to care about.
So write a normal inline function ... and pass it to lexigraphicalcompare
Good Luck
But an inlined function has, by definition, no address.
Therefore, if you take the address of the function and pass it to lexicographical_compare, it will not be inlined.
static or not, since the functor operator() call is inlined, the *this pointer will never be passed... because there is no function call in the first place.
[Questions (STFW) | GDNet Start Here | GDNet Search | Forum FAQ | Google | Asking Smart Questions ]
[Docs (RTFM) | MSDN | SGI's STL | OpenGL | File formats]
[C++ Must Haves (RTFS) | MinGW | Boost | Loki | FLTK | SDL ]
Stolen from Magmai Kai Holmlor, who held it from Oluseyi, who was inspired by Kylotan...
[edited by - Fruny on April 30, 2002 4:22:20 PM]
Therefore, if you take the address of the function and pass it to lexicographical_compare, it will not be inlined.
static or not, since the functor operator() call is inlined, the *this pointer will never be passed... because there is no function call in the first place.
[Questions (STFW) | GDNet Start Here | GDNet Search | Forum FAQ | Google | Asking Smart Questions ]
[Docs (RTFM) | MSDN | SGI's STL | OpenGL | File formats]
[C++ Must Haves (RTFS) | MinGW | Boost | Loki | FLTK | SDL ]
Stolen from Magmai Kai Holmlor, who held it from Oluseyi, who was inspired by Kylotan...
[edited by - Fruny on April 30, 2002 4:22:20 PM]
template <typename T>struct ci_char_traits : public std::char_traits<T>{ static bool eq(const T& lhs, const T& rhs) { return tolower(lhs) == tolower(rhs); } static bool ne(const T& lhs, const T& rhs) { return tolower(lhs) != tolower(rhs); } static bool lt(const T& lhs, const T& rhs) { return tolower(lhs) < tolower(rhs); } static int compare(const T* s1, const T* s2, size_t n) { return memicmp((void*)s1, (void*)s2, n * sizeof(T)); } static const T* find(const T* str, size_t count, const T& ch) { for(size_t i = 0; i < count; ++i) { if(utility::ci_char_traits<T>::eq(str[i], ch)) { return str + i; } } return NULL; }};typedef std::basic_string<char, ci_char_traits<char> > ci_string;typedef std::basic_string<wchar_t, ci_char_traits<wchar_t> > wci_string;
ci_strings will then be case-insensitively compared; they could be easily altered to take a locale. There are some issues; the various iostream overloads [annoyingly and as far as I can tell unnecessarily] assume that the traits of the string are the same as the traits of the stream, but it works well enough. And for things like Win32, which are generally case insensitive (for things like filenames and extensions, registry keys, and so on), it can save a lot of calls to nasty C-string functions.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement