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 Jul 01 '09 at 09:24
-
1see http://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c , I'd recommend either the Boost solution or extracting c_str and using wcscasecmp/_wcsicmp – Hasturkun Jul 01 '09 at 09:35
-
@Hasturkun: Thanks for the link. I vaguely remembered reading this on SO. – Naveen Jul 01 '09 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
}
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
}
-
12that if(stringA == stringB) forces me to leave a comment! :) should be return (stringA == stringB) – Idan K Jul 01 '09 at 09:37
-
4This solution will not work in several locales, in some languages when you convert to uppercase and then back you get different strings. – Stan Jul 01 '09 at 09:40
-
3You didn't just compare the strings, you have actually made both strings UPPERCASE regardless of the outcome. Try writing a method with the signature `bool compare(const wstring stringA, const wstring stringB)`, then fix this algorithm. – Zak Jul 12 '14 at 21:14
-
1
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
}
};

- 11,148
- 4
- 27
- 40

- 4,705
- 3
- 24
- 22
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

- 10,637
- 9
- 41
- 51
#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;
}

- 5,637
- 1
- 23
- 18
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;
}

- 94,250
- 39
- 176
- 234
-
4+1. (second[i] ^ 32) is interesting. I never knew this was how ascii was designed! – Sahas Jul 01 '09 at 11:38
-
3This will consider `[` 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. – interjay Jun 11 '13 at 13:38
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;

- 14,123
- 2
- 39
- 62
You can use mismatch() or lexicographical_compare(). This is suggested by Scott Meyers in Effecitve STL, item 35.

- 127,556
- 20
- 111
- 121
-
2
-
2Note that neither of these functions will compare case-insensitively by default. You would still have to write a function that compares characters case-insensitively and pass it to those functions. – Geerad Jul 01 '09 at 10:26