strcmpi for wstring that has suport for internationalization

Is there a function like strcmpi that works with wstring and string, and has suport for internationalization?

If not, does anyone have code for case insensitive strcmp function for both string and wstring that uses locale?
GoodInfo4117Asked:
Who is Participating?
 
AxterConnect With a Mentor Commented:
>>Is there a function like strcmpi that works with wstring
>>and string, and has suport for internationalization?

No.

You can try the following class and function.
They don't take locale as a variable, but instead they take the string used to create a locale.


#include <iostream>
#include <algorithm>
#include <string>
#include <locale>

class StrICmp
{
public:
     StrICmp(const std::string &Lang = "english") : m_locE(Lang.c_str())
     {
     }
     class CharLessI
     {
     public:
          CharLessI(std::locale &locE) : m_locE(locE)
          {
          }
          template<typename T>
               bool operator()(T c1, T c2)
          {
               return std::tolower(c1, m_locE) < std::tolower(c2, m_locE);
          }
     private:
          std::locale &m_locE;
     };
     template<typename T>
          int operator()(const T &s1, const T &s2)
     {
          if (std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), CharLessI(m_locE)))
               return -1;
          if (std::lexicographical_compare(s2.begin(), s2.end(), s1.begin(), s1.end(), CharLessI(m_locE)))
               return 1;
          return 0;
     }
private:
     std::locale m_locE;
};

template<typename T>
int StrCmpI(const T &s1, const T &s2, const std::string &Lang = "english")
{
     return StrICmp(Lang)(s1, s2);
}
0
 
gandalf79Commented:
I assume you are trying to use STL since you mentioned the wstring and string variable names. The nice thing about STL is you can use any character varialbe without having to worry about writing a hole new sting class. this includes wchar_t as seen below.

typedef basic_string<wchar_t> wstring;

if I understand what you want to do corrctly this should do something similar to what you want.

void main() {
     std::wstring str1, str2;
     wchar_t* wcharStr1 = new wchar_t[10];
     wchar_t* wcharStr2 = new wchar_t[10];

     wcharStr1 = (wchar_t*)"xxxx";
     wcharStr2 = (wchar_t*)"yyyy";

     str1.assign(wcharStr1);
     str2.assign(wcharStr2);

     std::wcout << str1 << ":" << str2 << std::endl;

     str2.assign(str1);

     std::wcout << str1 << ":" << str2 << std::endl;
}

i am not sure of the characters placed in wcharStr1 and wcharStr2 because my computer does not support wide characters in this way, so I am unable to over come this obstical. However if you can get passed this it should work for you.

You can also use any other functions from the basic_string class for wstring. hope this works for you.
0
 
AxterCommented:
Example Usage:

void Test1(void)
{
     const std::string Src_set1a = "This Is A Test";
     const std::string Src_set1b = "this is a tesT";
     int test1 = StrICmp()(Src_set1a, Src_set1b);
     
     const std::string Src_set2a = "This Is A Test";
     const std::string Src_set2b = "this is a tesTa";
     int test2 = StrCmpI(Src_set2a, Src_set2b);
     
     const std::string Src_set3a = "This Is A Testa";
     const std::string Src_set3b = "this is a tesT";
     int test3 = StrICmp()(Src_set3a, Src_set3b);
     
     std::cout << " test1 = " << test1 << " test2 = " << test2 << " test3 = " << test3 << std::endl;
     
     test1 = strcmpi(Src_set1a.c_str(), Src_set1b.c_str());
     test2 = strcmpi(Src_set2a.c_str(), Src_set2b.c_str());
     test3 = strcmpi(Src_set3a.c_str(), Src_set3b.c_str());
     
     std::cout << " test1 = " << test1 << " test2 = " << test2 << " test3 = " << test3 << std::endl;
}
void Test2(void)
{
     const std::wstring Src_set1a = L"This Is A Test";
     const std::wstring Src_set1b = L"this is a tesT";
     int test1 = StrICmp("english")(Src_set1a, Src_set1b);
     
     const std::wstring Src_set2a = L"This Is A Test";
     const std::wstring Src_set2b = L"this is a tesTa";
     int test2 = StrICmp("english")(Src_set2a, Src_set2b);
     
     const std::wstring Src_set3a = L"This Is A Testa";
     const std::wstring Src_set3b = L"this is a tesT";
     int test3 = StrICmp("english")(Src_set3a, Src_set3b);
     
     std::cout << " test1 = " << test1 << " test2 = " << test2 << " test3 = " << test3 << std::endl;
}

int main(int argc, char* argv[])
{
     Test1();
     Test2();
     system("pause");
     return 0;
}

0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
yonatCommented:
or you can write your own char_traits class, say case_insensitive_char_traits, and then use basic_string<char, case_insensitive_char_traits<char> > or basic_string<wchar_t, case_insensitive_char_traits<wchar_t> >.
0
 
GoodInfo4117Author Commented:
gandalf79,
I'm sorry, but I have no idea how your comment is related to my question.


Axter,
Your method is functional.  But I would think there would be a simpler method for this.  If I don't get a better answer, I'll accept yours.


yonat,
Would this method require less code then Axter's method?
If so, can you post a working example?
0
 
yonatCommented:
It's not much code, and the usage is nicer IMHO. Here is code to do it:
http://www.josuttis.com/libbook/string/icstring.hpp.html

And here is code + good explanation:
http://www.gotw.ca/gotw/029.htm
0
 
AxterCommented:
yonat,
Nice links
0
 
GoodInfo4117Author Commented:
yonat,
Thanks for the link, but I can't use it.  It doesn't support locale.
I need a method that can support any major language.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.