I am sure this would have been asked before but couldn't find it. Is there any built in (i.e. either using std::wstring's methods or the algorithms) way to case insensitive comparison the two wstring objects?
- 6Note, that case-insensitive comparisons are locale-dependent.avakar– avakar2009-07-01 09:24:31 +00:00Commented Jul 1, 2009 at 9:24
- 1see stackoverflow.com/questions/11635/… , I'd recommend either the Boost solution or extracting c_str and using wcscasecmp/_wcsicmpHasturkun– Hasturkun2009-07-01 09:35:53 +00:00Commented Jul 1, 2009 at 9:35
- @Hasturkun: Thanks for the link. I vaguely remembered reading this on SO.Naveen– Naveen2009-07-01 10:04:59 +00:00Commented Jul 1, 2009 at 10:04
8 Answers
If you don't mind being tied to Microsoft implementation you can use this function defined in <string.h>
int _wcsnicmp( const wchar_t *string1, const wchar_t *string2, size_t count ); But if you want best performance/compatibility/functionality ratio you will probably have to look at boost library (part of it is stl anyway). Simple example (taken from different answer to different question):
#include <boost/algorithm/string.hpp> std::wstring wstr1 = L"hello, world!"; std::wstring wstr2 = L"HELLO, WORLD!"; if (boost::iequals(wstr1, wstr2)) { // Strings are identical } 1 Comment
Using the standard library:
bool comparei(wstring stringA , wstring stringB) { transform(stringA.begin(), stringA.end(), stringA.begin(), toupper); transform(stringB.begin(), stringB.end(), stringB.begin(), toupper); return (stringA == stringB); } wstring stringA = "foo"; wstring stringB = "FOO"; if(comparei(stringA , stringB)) { // strings match } 4 Comments
bool compare(const wstring stringA, const wstring stringB), then fix this algorithm.You can use std::tolower() to convert the strings to lowercase or use the function wcscasecmp to do a case insensitive compare on the c_str()'s.
Here is a comparison functor you can use directly as well:
struct ci_less_w { bool operator() (const std::wstring & s1, const std::wstring & s2) const { #ifndef _WIN32 return wcscasecmp(s1.c_str(), s2.c_str()) < 0; #else return _wcsicmp(s1.c_str(), s2.c_str()) < 0; #endif } }; You could use the boost string algorithms library. Its a header only library as long as you're not going to do regex. So you can do that very easily.
http://www.boost.org/doc/libs/1_39_0/doc/html/string_algo.html
Comments
#include <algorithm> #include <string> #include <cstdio> bool icase_wchar_cmp(wchar_t a, wchar_t b) { return std::toupper(a) == std::toupper(b); } bool icase_cmp(std::wstring const& s1, std::wstring const& s2) { return (s1.size() == s2.size()) && std::equal(s1.begin(), s1.end(), s2.begin(), icase_wchar_cmp); } int main(int argc, char** argv) { using namespace std; wstring str1(L"Hello"), str2(L"hello"); wprintf(L"%S and %S are %S\n", str1.c_str(), str2.c_str(), icase_cmp(str1,str2) ? L"equal" : L"not equal"); return 0; } Comments
Talking about English right ?! though I would go with my lovely Boost :)
bool isequal(const std::wstring& first, const std::wstring& second) { if(first.size() != second.size()) return false; for(std::wstring::size_type i = 0; i < first.size(); i++) { if(first[i] != second[i] && first[i] != (second[i] ^ 32)) return false; } return true; } 2 Comments
[ to be the same as {, and * to be the same as a newline, along with many other such inaccuracies. Besides, assuming English when dealing with wide strings is almost certainly wrong.If you need that the string will always make case insensitive comparation (when using operators == or !=), then a possible elegant solution is to redefine char_traits::compare method.
Define your own structure. Example
struct my_wchar_traits: public std::char_traits< wchar_t> { static int compare( const char_type* op1, const char_type* op2, std::size_t num) { // Implementation here... any of the previous responses might help... } }; Then, define your own case insensitive string:
typedef std::basic_string< wchar_t, my_wchar_traits> my_wstring; Comments
You can use mismatch() or lexicographical_compare(). This is suggested by Scott Meyers in Effecitve STL, item 35.